【问题标题】:Can I match multiline string in python without using re.DOTALL? [duplicate]我可以在不使用 re.DOTALL 的情况下匹配 python 中的多行字符串吗? [复制]
【发布时间】:2015-05-15 06:20:24
【问题描述】:

我正在尝试用 python 编写一个简单的词法分析器。 我正在使用正则表达式来做到这一点。 所以,我需要一个匹配多行注释的正则表达式:

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

通过使用这种模式:

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

并用

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

它有效。

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

【问题讨论】:

  • 使用包含点和换行符的字符类。
  • 你需要转义星号。
  • 你可能想要r'/\*.*?\*/';注意.*? 而不是.*。这将使正则表达式为您提供可能的最短匹配,而不是可能的最长匹配。在/* a */ b /* c */ 之类的输入上尝试一下...我猜你想要两个匹配,而不是一个。
  • 您能否详细说明 dotall 和单引号字符串有什么问题?如果你试图解析 c 风格的 cmets,这不是办法。

标签: python regex


【解决方案1】:

您可以通过使用类似[\s\S] 这样的小技巧来达到同样的目的。

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

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

您可以像这样使用正则表达式:

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

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

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

Working demo

你可以在下面看到这个技巧是如何工作的:

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

/* A */
/* B */

您的正则表达式将错误地匹配 /* A *//* B */。您必须添加 ? 才能将其设置为不贪婪:

/\*.*?\*/
     ^--- ungreedy

【讨论】:

    【解决方案2】:

    除了re.XXX 常量,您还可以使用内联标志:

    re.match('(?s)/\*.*?\*/', stuff)
    

    来自docs

    (?iLmsux) (来自集合'i'、'L'、'm'、's'、'u'、'x'的一个或多个字母。)组匹配空字符串;这些字母设置了相应的标志:re.I(忽略大小写)、re.L(取决于语言环境)、re.M(多行)、re.S(点匹配所有)、re.U(取决于 Unicode)和re.X(详细),用于整个正则表达式。

    我更喜欢 re.XXX 标志的内联,原因有两个:1) 表达式是独立的,2) 无需使用 compile 或将 flags 参数附加到每个 re. 调用。

    【讨论】:

    • 您不必使用compile,您可以将标志传递给例如re.match().
    • @DietrichEpp:谢谢,我忘了。从来没有以这种方式使用过标志。
    【解决方案3】:

    如果我们想列举所有可能性,我也会发布我的答案:

    /\*(?:[\r\n]|[^\r\n])*\*/

    example here

    但是,使用您的示例计算需要 147 步,而 Fede 的 /\*[\s\S]*\*/ 只需要 12 步。

    如果我们比较具有捕获组的版本之间的性能 - /\*((?:[\r\n]|[^\r\n])*)\*//\*([\s\S]*?)\*/,比例已经不是那么大了:151 对 97 步。

    【讨论】:

    • 在这里使用交替不是一个好主意。大多数正则表达式引擎并没有真正优化这里的字符类,因此它会在每个匹配的字符后创建一个选择点,而(?s).[\s\S] 方法不会创建任何选择点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2019-10-23
    • 2013-04-03
    • 2015-08-04
    相关资源
    最近更新 更多