Flex

时间:2018-10-14 12:11:45

标签: 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将整个事物作为单个令牌返回。我该怎么办?

1 个答案:

答案 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 conditionsthis answer中有一个非常相似的解决方案的完整示例。

相关问题