Использование экранированного символа (maigc) в качестве границы в диапазоне символов в шаблонах Lua - PullRequest
0 голосов
/ 10 ноября 2018

Руководство Lua в разделе 6.4.1 о состояниях Lua Patterns

Класс символов используется для представления набора символов. в описании класса символов допускаются следующие комбинации:

  • x: (где x не является одним из магических символов ^$()%.[]*+-?) представляет сам символ x.
  • .: (точка) представляет все символы.
  • %a: представляет все буквы.
  • %c: представляет все управляющие символы.
  • %d: представляет все цифры.
  • %g: представляет все печатные символы, кроме пробела.
  • %l: представляет все строчные буквы.
  • %p: представляет все знаки пунктуации.
  • %s: представляет все пробелы.
  • %u: представляет все заглавные буквы.
  • %w: представляет все буквенно-цифровые символы.
  • %x: представляет все шестнадцатеричные цифры.
  • % x: (где x - любой не алфавитно-цифровой символ) представляет символ x. Это стандартный способ избежать магических персонажей. Любой не буквенно-цифровой символ (включая все знаки пунктуации, даже немагическому) может предшествовать % при использовании для обозначения сам в мире.
  • [set]: представляет класс, который является объединением всех символов в set. Диапазон символов может быть указан путем разделения конца символы диапазона, в порядке возрастания, с -. Все классы %x, описанный выше, также может использоваться в качестве компонентов в комплекте. Все остальные символы в set представляют себя. Например, [%w_] (или [_%w]) представляет все буквенно-цифровые символы плюс подчеркивание, [0-7] представляет восьмеричные цифры, а [0-7%l%-] представляет восьмеричные цифры плюс строчные буквы плюс символ -.

Вы можете поместить закрывающую квадратную скобку в набор, позиционируя ее как первый персонаж в наборе. Вы можете поставить дефис в набор позиционируя его как первый или последний символ в наборе. (Вы можете также используйте escape для обоих случаев.)

Взаимодействие между диапазонами и классами не определено. Поэтому шаблоны типа [% a-z] или [a - %%] не имеют значения.

[^set]: представляет собой дополнение набора, где набор интерпретируется как указано выше.

Для всех классов, представленных отдельными буквами (%a, %c и т. Д.), соответствующая заглавная буква представляет собой дополнение класса. Например,% S представляет все непробельные символы.

Определения букв, пробелов и других групп символов зависят от текущая локаль. В частности, класс [a-z] не может быть эквивалентно %l.
(выделено мной выделением и некоторым форматированием)

Итак, поскольку "взаимодействие диапазонов и классов не определено." , как создать класс символов set, который начинается и / или заканчивается (магическим) символом, который должен сбежать?

Например,

[%%-c]

не определяет класс символов в диапазоне от % до c и включает все промежуточные символы, но набор, состоящий только из трех символов %, - и c.

1 Ответ

0 голосов
/ 10 ноября 2018

Взаимодействие между диапазонами и классами не определено.

Очевидно, что это не жесткое и быстрое правило (для наборов символов регулярных выражений в целом), а решение по реализации Lua. Хотя использование сокращенных символов в наборах символов / диапазонах работает в некоторых (большинстве) разновидностях регулярных выражений, это не во всех (как в модуле re Python, demo ).

Однако второй пример вводит в заблуждение:

Следовательно, шаблоны типа [% a-z] или [a - %%] не имеют значения.

Хотя с первым примером все в порядке, поскольку %a является сокращенным классом (который представляет все буквы) в set, [%a-z] не определен и вернет nil в случае совпадения со строкой.

Экранированные символы в диапазоне [set]

Во втором примере [a-%%], %% просто определяет экранированный знак%, а не класс сокращенных символов. Поверхностная проблема заключается в том, что диапазон определен с повышением , от high до low (по отношению к US ASCII значению символов a 61 и % 37 ), например, как ошибочный шаблон Lua, такой как [f-a]. Если набор определен в обратном порядке, он , кажется, работает : [%%-a], но все, что он делает, - это сопоставление трех отдельных символов вместо диапазона символов от % до a; кредит велосипедист ).

Это может считаться ошибкой и, действительно, означает, что невозможно создать диапазон символов в [set], если необходимо экранировать один из определяющих символов диапазона.

Возможное решение

Начните диапазон символов со следующего символа, который не нужно экранировать, а затем добавьте остальные экранированные символы по отдельности, например,

[%%&-a]

Sample

for w in string.gmatch("%&*()-0Aa", "[%%&-a]") do
  print(w)
end

Это ответ, который я нашел. Тем не менее, может быть, у кого-то есть что-то лучше.

...