Flex 中文字内的多行匹配

Dim*_*htz 0 c regex flex-lexer

我想里面匹配的文本%[,并]%在单个或多个行。我尝试的第一件事是:

\%\[(.*?)\]\%              return MULTILINE_TEXT;
Run Code Online (Sandbox Code Playgroud)

但这仅适用于单行情况,不适用于多行。所以,我想我可以使用/s

/\%\[(.*?)\]\%/s           return MULTILINE_TEXT;
Run Code Online (Sandbox Code Playgroud)

但 flex 将此视为无效规则。我尝试的最后一件事是:

\%\[((.*?|\n)*?)\]\%       return MULTILINE_TEXT;
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但它并没有停止在第一个]%。在以下示例中:

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

... other stuff ...

%[ Some more text ...
   Some more text ... ]%
Run Code Online (Sandbox Code Playgroud)

flex 会将整个事物作为单个标记返回。我能做什么?

ric*_*ici 5

请注意,*?不是由柔性非贪婪匹配处理。

Flex 确实支持一些正则表达式标志,但其语法与大多数正则表达式库略有不同。例如,您可以.通过设置s标志来改变 的含义;更改适用括号内的区域(而不是遵循标志设置,如 PCRE):

"%["(?s:.*)"%]"
Run Code Online (Sandbox Code Playgroud)

更常见的是与 lex 兼容的用法:

"%["(.|\n)*"%]"
Run Code Online (Sandbox Code Playgroud)

您还可以将x标志用于更易读的正则表达式:

(?xs: "%[" .* "%]" )
Run Code Online (Sandbox Code Playgroud)

(该x标志在定义中不起作用,仅在模式规则中起作用。)

带引号的字符串(如上)是另一种 (f) 特定于 lex 的语法,它比反斜杠转义更具可读性,尽管反斜杠转义也有效。但是 flex 没有实现 PCRE/Gnu/JS 扩展,例如\w\s

有关flex 正则表达式的完整指南,请参阅flex 手册;如果您习惯了其他正则表达式语法,这绝对值得一读。

您可能会发现 (f)lex 不支持许多常见的正则表达式扩展,包括非贪婪匹配,这令人失望。这使得为​​由多个字符终止的模式编写模式变得很尴尬,就像你的例子一样。如果分隔符%[%]不能嵌套,因此您确实希望匹配以第一个结尾,则%]可以使用以下内容:

%\[([^%]|%+[^]])*%+\]   or  (?x: "%[" ( [^%] | %+ [^]] )* %* "%]" ) 
Run Code Online (Sandbox Code Playgroud)

这有点难以阅读,但它是精确的:%[后跟任意次数的重复,或者是一个字符以外的字符,%或者是一个序列,%后跟一个不是]的序列,以一个序列结束,%然后是一个]

在上面的模式中,你需要%+而不是% 处理像这样的字符串:

%[%% text surrounded by percents%%%]
Run Code Online (Sandbox Code Playgroud)

允许嵌套的更易读的解决方案%[是使用开始条件这个答案中有一个非常相似的解决方案的完整示例。