我可以在不使用re.DOTALL的情况下匹配python中的多行字符串吗?

时间:2015-03-12 21:48:45

标签: python regex

我试图在python中编写一个简单的词法分析器。 我正在使用正则表达式来完成它。 所以,我需要一个匹配多行注释的正则表达式:

/* first line.
the second line
The last line. */

使用这种模式:

pattern = r"/\*.*\*/" 

并使用

进行编译
regex = re.compile(pattern,re.DOTALL) 

它有效。

现在,我不会使用re.DOTALL,'因为这也适用于单引号字符串。 有没有办法编译这个表达式,以便在没有re.DOTALL?

的情况下工作

3 个答案:

答案 0 :(得分:2)

你可以通过使用像[\s\S]这样的小技巧来实现同样的目标。

[\s\S]背后的想法是捕获所有内容,因此您可以使用显式模式划分您想要的内容。例如:

/\*        <--- Match /*
[\s\S]*?   <--- Match everything (ungreedy)
\*/        <--- Match */

你可以使用这样的正则表达式:

/\*[\s\S]*?\*/

如果您想捕获评论中的内容,那么您可以这样做:

/\*([\s\S]*?)\*/

<强> Working demo

您可以在下面看到这个技巧的作用:

enter image description here

顺便说一句,您使用的是贪婪的正则表达式/\*.*\*/,它会错误地匹配评论。例如,如果你有:

/* 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步。