【问题标题】:Non greedy regular expression not matching what I expected非贪婪的正则表达式不符合我的预期
【发布时间】:2016-06-03 19:24:20
【问题描述】:

我正在文本中搜索在行中使用“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)。

【问题讨论】:

    标签: regex non-greedy


    【解决方案1】:

    ^[^;]*?variable2

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

    Demo

    ^[^;\n]*?variable2

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

    Demo

    【讨论】:

      【解决方案2】:

      你在这里得到了一个惰性匹配不正确的关键点:它不会尝试找到整体上可能的最短匹配,但它会尝试从一开始就找到可能的最短匹配。让我们用一个更短的正则表达式来展示这一点:a*?b。给定一个字符串aab,你期望惰性匹配匹配ab,但它匹配aab

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

      【讨论】:

      • 是的,我认为它会主动寻找一组较短的字符来匹配。我一直称它为非贪婪,但懒惰是一个更具描述性的词。
      【解决方案3】:

      您可以使用否定前瞻

      ^(?:(?!;).)+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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多