Многострочное совпадение внутри литералов во Flex - PullRequest
0 голосов
/ 14 октября 2018

Я пытаюсь сопоставить текст внутри %[ и ]% в одну или несколько строк.Первое, что я попробовал, было:

\%\[(.*?)\]\%              return MULTILINE_TEXT;

, но это работает только для случаев с одной строкой, а не для нескольких строк.Итак, я подумал, что мог бы использовать /s:

/\%\[(.*?)\]\%/s           return MULTILINE_TEXT;

Но flex рассматривал это как недопустимое правило.Последнее, что я попробовал, было:

\%\[((.*?|\n)*?)\]\%       return MULTILINE_TEXT;

, который, казалось, работал, но не останавливался на первом ]%.В следующем примере:

%[ Some text ...
   Some text ... ]%

... other stuff ...

%[ Some more text ...
   Some more text ... ]%

flex вернет всю вещь как один токен.Что я могу сделать?

1 Ответ

0 голосов
/ 14 октября 2018

Обратите внимание, что *? - это , а не , который Flex рассматривает как не жадное совпадение.

Flex поддерживает некоторые флаги регулярных выражений, но его синтаксис немного отличается от большинства библиотек регулярных выражений.,Например, вы можете изменить значение ., установив флаг s;изменение применяется к региону в скобках (и не после установки флага, как в PCRE):

"%["(?s:.*)"%]"

Чаще встречается использование, совместимое с lex:

"%["(.|\n)*"%]"

Вы также можете использовать флаг x для немного более удобочитаемых регулярных выражений:

(?xs: "%[" .* "%]" )

(флаг x не работает в определениях, только в правилах шаблонов.)

Строки в кавычках (как указано выше) - это другой (f) специфичный для lex синтаксис, который может быть более читабельным, чем экранирование с обратной косой чертой, хотя экранирование с обратной косой чертой также работает.Но flex не реализует расширения PCRE / Gnu / JS, такие как \w и \s.

. См. руководство по флексам для полного руководства по регулярным выражениям flex;это определенно стоит прочитать, если вы привыкли к другим синтаксисам регулярных выражений.

Возможно, вас разочарует, что (f) lex не поддерживает много распространенных расширений регулярных выражений, в том числе не жадные совпадения.Это затрудняет написание шаблонов для шаблонов, оканчивающихся несколькими символами, как в вашем примере.Если разделители %[ и %] не могут быть вложенными, так что вы действительно хотите, чтобы матч заканчивался первым %], вы можете использовать что-то вроде этого:

%\[([^%]|%+[^]])*%+\]   or  (?x: "%[" ( [^%] | %+ [^]] )* %* "%]" ) 

Это немного сложночитать, но это точно: %[, за которым следует любое количество повторений либо символа, отличного от %, либо последовательности %, за которой следует что-то отличное от ], заканчивающееся последовательностью %сопровождаемый ].

В приведенном выше шаблоне вам нужно %+ вместо % для работы со строками, такими как:

%[%% text surrounded by percents%%%]

Более читаемое решение, которое также допускает вложенные %[, заключается виспользуйте условия запуска .Полный пример очень похожего решения есть в этом ответе .

...