正则表达式优化:负字符类“[^#]”使多行标志“m”无效

时间:2014-01-24 15:21:22

标签: regex

我正在尝试逐行解析文本,捕获除了特定标记后的所有内容,例如#。没有逃避考虑,非常基本。

例如,如果输入文本是:

Multiline input text
Mid-sentence# cut, this won't be matched
Hey there

如果想要检索

['Multiline input text',
 'Mid-sentence',
 'Hey There']

这适用于/(.*?)(?:#.*$|$)/mg(即使有一些空匹配)。但是,如果我尝试使用/([^#]++)(?:#.*$|$)/mg改进正则表达式(通过避免回溯并删除空匹配),则返回

[
"Multiline input text
Mid-sentence",
"
Hey There"
]

好像[^#]包含换行符,即使打开多行标记也是如此。据我所知,我可以通过在类字符中添加[^#\n\r]来解决这个问题,但是这会使多行选项变得无用,我担心它会在某些环境/编码中打破一些奇怪的换行符。 / p>

您是否有人知道这种行为的原因,以及是否还有另一种解决方法?谢谢!

修改 最初,它发生在PCRE中。但即使在/([^#]+)(?:#.*$|$)/mg的Javascript中,也存在相同的多线行为。我知道我可能会使用该语言逐行解析文本,但我只想用正则表达式来做。

2 个答案:

答案 0 :(得分:3)

您似乎错误地定义了/m。此标志唯一的作用是更改^$匹配的内容,以便它们也分别在行的开头和结尾匹配。它不会影响其他任何事情。如果您不想匹配换行符,则应按照建议进行操作并使用[^#\n\r]

答案 1 :(得分:2)

适用于您的正则表达式是:

^(.*?)(?:#.*|)$

在线演示:http://regex101.com/r/aP8eV6

DIfference使用.*?代替[^#]+

  • [^#]+根据定义匹配#以外的任何内容,并且还包含换行符。
  • 多行标记m仅允许您在多行输入中使用行开始/结束锚点^ and $