我正在尝试将%[
和]%
中的文本单行或多行匹配。我尝试的第一件事是:
\%\[(.*?)\]\% 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将整个事物作为单个令牌返回。我该怎么办?
答案 0 :(得分:4)
请注意,*?
被Flex视为非贪婪匹配。
Flex确实支持某些正则表达式标志,但其语法与大多数正则表达式库略有不同。例如,您可以通过设置.
标志来更改s
的含义;更改适用于括号内 的区域(并且不遵循标志设置,如PCRE):
"%["(?s:.*)"%]"
查看lex兼容用法更为常见:
"%["(.|\n)*"%]"
您也可以将x
标志用于可读性更高的正则表达式:
(?xs: "%[" .* "%]" )
(x
标志在定义中无效,仅在模式规则中有效。)
带引号的字符串(如上)是另一种(f)lex特定的语法,尽管反斜杠转义也可以使用,但比反斜杠转义更具可读性。但是flex无法实现PCRE / Gnu / JS扩展,例如\w
和\s
。
有关弹性正则表达式的完整指南,请参见the flex manual;如果您习惯其他正则表达式语法,绝对值得一读。
您可能会发现令人失望的是(f)lex不支持许多常见的正则表达式扩展,包括非贪婪匹配。就像您的示例一样,这样做很难为以多个字符结尾的模式编写模式。如果定界符%[
和%]
无法嵌套,那么您确实希望匹配以第一个%]
结尾,则可以使用以下方式:
%\[([^%]|%+[^]])*%+\] or (?x: "%[" ( [^%] | %+ [^]] )* %* "%]" )
这很难读,但是很准确:%[
后跟任意重复的%
以外的其他字符或%
的序列后跟其他比]
大,以%
后接]
的序列结尾。
在上述模式中,您需要%+
而不是%
来处理以下字符串:
%[%% text surrounded by percents%%%]
一种更易读的解决方案(也允许嵌套%[
)是使用start conditions。 this answer中有一个非常相似的解决方案的完整示例。