c - Flex 中文字内的多行匹配

标签 c regex flex-lexer

我试图在单行或多行中匹配 %[]% 中的文本。我尝试的第一件事是:

\%\[(.*?)\]\%              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/

相关文章:

compiler-construction - BISON + FLEX 语法 - 为什么标记被连接在一起

c - 如何将 GNU readline 与 flex-lexer 一起使用?

c - 局部静态变量如何在方法中工作?

Java 正则表达式 - 条件分组

regex - sed 尝试在搜索和替换中使用捕获组时前面的正则表达式无效

php - preg_replace 用奇怪的字符替换引号?

c - 优先队列插入

c - 如何使这个程序在c中高效?

c - Linux下共享内存映射

在没有参数的情况下在 bison 中调用 yyrestart 函数导致 El Capitan 上出现 sigsegv