Количество повторений символов в настройке паттерна Lua

Я ищу количество повторений символов в настройке шаблона Lua. Пытаюсь проверить количество символов в строке. Как я читал в руководстве, даже с классами символов это все еще очень ограничивает, потому что мы можем только соответствовать строкам фиксированной длины.

Чтобы решить эту проблему, шаблоны поддерживают эти четыре оператора повторения:

  • '*' Соответствует предыдущему символу (или классу) ноль или более раз, насколько это возможно.
  • '+' Соответствует предыдущему символу (или классу) один или несколько раз, насколько это возможно.
  • '-' Соответствует предыдущему символу (или классу) ноль или более раз, как можно меньшее количество раз.
  • '?' Сделайте предыдущий символ (или класс) необязательным.

Итак, нет информации о фигурных скобках {}, например,

{1,10}; {1,}; {10};

не работает.

local np = '1'
local a =  np:match('^[a-zA-Z0-9_]{1}$' )

возвращает np = nil.

local np = '1{1}'
local a =  np:match('^[a-zA-Z0-9_]{1}$' )

возвращает np = '1{1}' :)

Этот url говорит, что нет таких волшебных символов:

Некоторые символы, называемые магическими символами, имеют особое значение при использовании в шаблоне. Волшебные персонажи

( ) . % + - * ? [ ^ $

Фигурные скобки работают только как простой текст и не более того. Я прав? Как лучше всего избежать этой «ошибки»?

Можно прочитать обычное использование фигурных скобок, например, здесь.


person Vyacheslav    schedule 01.10.2015    source источник
comment
Lua его не предоставляет. Вы можете повторять самостоятельно, например (_ 1_ равно %d%d+). Также вы можете использовать библиотеку Lua rex pcre.   -  person moteus    schedule 01.10.2015
comment
@moteus, очень чудовищно и некрасиво юзабилити. но спасибо за идею.   -  person Vyacheslav    schedule 01.10.2015
comment
Шаблон Lua не поддерживает полный набор функций регулярных выражений Perl. Подтяжки не поддерживаются. Использовать явный счетчик: np:match('^'..('[%w_]'):rep(k)..'$')   -  person Egor Skriptunoff    schedule 01.10.2015
comment
@EgorSkriptunoff, не сильно ли увеличивает расчеты?   -  person Vyacheslav    schedule 01.10.2015
comment
@trololo - Regex никогда не был быстрым. Это всегда интенсивно загружает процессор. Найдите другие подходы для более быстрого расчета: #np==k and not np:find'[^%w_]'   -  person Egor Skriptunoff    schedule 01.10.2015
comment
Еще одно ограничение для поддерживаемых квантификаторов: В отличие от некоторых других систем, в Lua модификатор может применяться только к классу символов; нет возможности группировать паттерны под модификатором. Попробуйте с библиотекой PCRE: > require "rex_pcre" > return rex_pcre.new("^[a-zA-Z0-9_]{2}$"):exec("12").   -  person Wiktor Stribiżew    schedule 01.10.2015
comment
@EgorSkriptunoff, я думаю, вы правы: заранее проверить длину строки в моем простом случае - это наиболее удобное решение без использования внешних библиотек.   -  person Vyacheslav    schedule 01.10.2015
comment
@stribizhev, спасибо, попробую.   -  person Vyacheslav    schedule 01.10.2015


Ответы (1)


Нельзя не признать, что квантификаторы регулярных выражений Lua очень ограничены в функциональности.

  1. Это как раз те 4, которые вы упомянули (+, -, * и ?)
  2. Нет поддержки ограничивающих кванторов (те, которые вам нужны)
  3. В отличие от некоторых других систем, в Lua модификатор может применяться только к классу символов; нет возможности сгруппировать шаблоны по модификатору (см. исходный код). К сожалению, шаблоны Lua не поддерживают это ('(foo)+' или '(foo|bar)'), только отдельные символы могут повторяться или выбираться между , а не подшаблоны или строки.

В качестве «обходного пути», чтобы использовать ограничивающие квантификаторы и все другие привилегии регулярных выражений PCRE, вы можете использовать _ 7_ библиотека.

Или, как предлагает @moteus, частичный обходной путь для «эмуляции» ограничивающих квантификаторов, имеющих только нижнюю границу, просто повторите шаблон, чтобы сопоставить его несколько раз, и примените доступный квантификатор Lua к последнему. Например. для совпадения 3 или более шаблона:

local np = 'abc_123'
local a = np:match('^[a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_]+$' )

См. демонстрацию IDEONE

Другой библиотекой, которую следует рассмотреть вместо PCRE, является Lpeg.

person Wiktor Stribiżew    schedule 01.10.2015
comment
Спасибо за обобщение комментариев. - person Vyacheslav; 01.10.2015
comment
Просто замечу: [a-zA-Z0-9_] можно заменить на [_%w], что немного сократит этот шаблон. - person ryanpattison; 01.10.2015