非贪婪的正则表达式与我的预期不符

时间:2016-06-03 19:24:21

标签: regex non-greedy

我在文本中搜索行中使用“variable2”而没有分号的行。这是我的正则表达式来解决这个问题。

^[^;]*?variable2

我对此的理解是它应该找到以换行符开头的文本,该换行符最小化非分号字符后跟“variable2”的数量。 这无法在此示例中选择我期望的内容。


Label0: mov     variable0,WREG             ;Some comment
        mov     W0,variable1

Label1: btsc    variable2,#1               ;Some other comment
        bra     label2

我希望得到这个

Label1: btsc    variable2

但是选择了

        mov     W0,variable1

Label1: btsc    variable2

我误解了什么?在我看来,非贪婪的表达并没有按照我的意图去做。如果我将正则表达式更改为^[^;\n]*?variable2,它会选择我希望它选择的内容。我使用Sublime Text 2作为正则表达式,但我似乎在php,javascript和python中得到了相同的结果(根据regex101.com)。

3 个答案:

答案 0 :(得分:2)

^[^;]*?variable2

此正则表达式从行的开头到;匹配除variable2以外的任何内容。由于第2行和第3行(只是换行符)也不包含任何;匹配从第2行的开头到variable2。由于您使用的是多行模式,^充当每行的锚点。

Demo

^[^;\n]*?variable2

此正则表达式从行的开头到变量2匹配除;\n以外的任何内容。第2行和第3行不匹配,因为它们包含\n

Demo

答案 1 :(得分:1)

你在这里得到了一个关键的懒惰匹配错误:它没有尝试找到总体上最短的匹配,但它试图从头开始找到最短的匹配。让我们用一个更短的正则表达式来表示:a*?b。给定字符串aab,您希望延迟匹配与ab匹配,但它与aab匹配。

正则表达式解析器以字符串中的第一个字符(第一个a)开头,并将其与惰性匹配。然后它继续,但无法匹配b,因为第二个字符仍然是a。然后,它会展开a*?模式以匹配aa,现在可以成功匹配b,从而获得整体匹配aab

答案 2 :(得分:0)

您可以使用否定前瞻

^(?:(?!;).)+variable2

请参阅a demo on regex101.com(并注意multiline修饰符!)。

^           # matches the beginning of the line
(?:(?!;).)+ # match any character except a newline
            # and make sure what immediately follows
            # is not a semicolon 
variable2   # match variable2