我试图在单行或多行中匹配 %[
和 ]%
中的文本。我尝试的第一件事是:
\%\[(.*?)\]\% 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 会将整个事物作为单个标记返回。我能做什么?
最佳答案
请注意 *?
不被 flex 视为非贪婪匹配。
Flex 确实支持一些正则表达式标志,但它的语法与大多数正则表达式库略有不同。例如,您可以通过设置 s
标志来改变 .
的含义;更改适用于括号内的区域(而不是像在 PCRE 中那样遵循标志设置):
"%["(?s:.*)"%]"
比较常见的是看lex兼容的用法:
"%["(.|\n)*"%]"
您还可以使用 x
标志来获得更具可读性的正则表达式:
(?xs: "%[" .* "%]" )
(x
标志在定义中不起作用,仅在模式规则中起作用。)
带引号的字符串(如上)是另一种特定于 (f)lex 的语法,它比反斜杠转义更具可读性,尽管反斜杠转义也有效。但是 flex 没有实现 \w
和 \s
等 PCRE/Gnu/JS 扩展。
参见 the flex manual有关 flex 正则表达式的完整指南;如果您习惯了其他正则表达式语法,那绝对值得一读。
您可能会感到失望,因为 (f)lex 不支持许多常见的正则表达式扩展,包括非贪婪匹配。这使得为由多个字符终止的模式编写模式变得很尴尬,就像您的示例一样。如果分隔符 %[
和 %]
不能嵌套,那么您真的希望匹配以第一个 %]
结束,您可以使用这样的东西:
%\[([^%]|%+[^]])*%+\] or (?x: "%[" ( [^%] | %+ [^]] )* %* "%]" )
这有点难读,但它是精确的:%[
后跟 %
以外的字符或 序列的任意次数的重复>%
后跟 ]
以外的内容,以 %
后跟 ]
的序列结尾。
在上面的模式中,你需要 %+
而不是 %
来处理像这样的字符串:
%[%% text surrounded by percents%%%]
也允许嵌套 %[
的更具可读性的解决方案是使用 start conditions . this answer 中有一个非常相似的解决方案的完整示例。 .
关于c - Flex 中文字内的多行匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52802496/