我试图在python中编写一个简单的词法分析器。 我正在使用正则表达式来完成它。 所以,我需要一个匹配多行注释的正则表达式:
/* first line.
the second line
The last line. */
使用这种模式:
pattern = r"/\*.*\*/"
并使用
进行编译regex = re.compile(pattern,re.DOTALL)
它有效。
现在,我不会使用re.DOTALL
,'因为这也适用于单引号字符串。
有没有办法编译这个表达式,以便在没有re.DOTALL?
答案 0 :(得分:2)
你可以通过使用像[\s\S]
这样的小技巧来实现同样的目标。
[\s\S]
背后的想法是捕获所有内容,因此您可以使用显式模式划分您想要的内容。例如:
/\* <--- Match /*
[\s\S]*? <--- Match everything (ungreedy)
\*/ <--- Match */
你可以使用这样的正则表达式:
/\*[\s\S]*?\*/
如果您想捕获评论中的内容,那么您可以这样做:
/\*([\s\S]*?)\*/
<强> Working demo 强>
您可以在下面看到这个技巧的作用:
顺便说一句,您使用的是贪婪的正则表达式/\*.*\*/
,它会错误地匹配评论。例如,如果你有:
/* A */
/* B */
你的正则表达式会错误地匹配/* A *//* B */
。您必须添加?
才能将其设置为不合格:
/\*.*?\*/
^--- ungreedy
答案 1 :(得分:1)
除re.XXX
常量外,您还可以使用内联标志:
re.match('(?s)/\*.*?\*/', stuff)
来自docs:
(?iLmsux) (来自集合中的一封或多封信件,&#39; L&#39;&#39; m&#39;&#39;&#39;&#39; u&# 39;,&#39; x&#39;。)该组匹配空字符串;字母设置相应的标志:re.I(忽略大小写),re.L(依赖于语言环境),re.M(多行),re.S(点匹配所有),re.U(取决于Unicode),以及re.X(详细),用于整个正则表达式。
我更喜欢内联到re.XXX
标志有两个原因:1)表达式是自包含的,2)不需要使用compile
或将flags
参数附加到每个{{} 1}}来电。
答案 2 :(得分:0)
如果我们想要列举所有可能性,我也会发布我的回答:
/\*(?:[\r\n]|[^\r\n])*\*/
请参阅example here。
但是,使用您的示例需要147步才能计算,而Fede /\*[\s\S]*\*/
只需要12步。
如果我们将版本与捕获组之间的效果进行比较 - /\*((?:[\r\n]|[^\r\n])*)\*/
和/\*([\s\S]*?)\*/
,则比率已经不那么大:151对97步。