【问题标题】:How does the regular expression "(aa)+\1" match "aaaaaa"?正则表达式“(aa)+\1”如何匹配“aaaaaa”?
【发布时间】:2013-08-24 14:57:02
【问题描述】:

谁能解释正则表达式引擎匹配(aa)+\1aaaaaa 的过程?我知道当您使用+* 时有一个称为回溯的过程,但我不确定它在此示例中是如何工作的。

【问题讨论】:

    标签: regex backtracking


    【解决方案1】:

    当您将量词放在捕获组之外时,它不会捕获与带有量词的该模式匹配的整个字符串。它只是匹配模式匹配的最后一个重复。

    所以,(aa)+ 不会在捕获组中捕获 aaaa,而只是捕获最后一对 - aa,这样它就可以满足正则表达式模式的其余部分。

    因此,对于 (aa)+\1,模式首先匹配 - aaaa,然后反向引用 \1 匹配捕获的组 - aa。因此匹配字符串 - aaaaaa。不是(aa)+ 不会匹配所有a's,因为这样就没有任何东西可以被\1 匹配。

    这是正则表达式(aa)+\1的分解:

    • (aa)+ 匹配字符串中的前两个 aa。剩余字符串 - aaaa
    • (aa)+ 还要匹配更多内容,所以继续匹配下一个 aa。剩余字符串 - aa
    • 再次(aa)+ 可以匹配剩余的字符串。所以它匹配下一个aa。剩余字符串 - ""。请记住,量词默认行为贪婪。它们会尽可能匹配。
    • 现在,(aa)+ 无法再匹配了。
    • 模式中的下一个是\1。但是没有什么可以匹配的了。
    • 回溯与(aa)+ 匹配的最后一个模式。剩余字符串 - "aa"
    • 现在\1 再次尝试匹配,它成功匹配aa,因为这是当前在第一个st 捕获组中的内容。

    参考资料:

    【讨论】:

    • 感谢您的出色回答!您能否评论一下如果我这样做会发生什么:(aa+)\1,我将量词放在捕获组中?
    • 也许我应该问另一个问题“(aa+)\1(aa)+\1 有何不同?
    • @bodacydo: (aa+)\1 将匹配您给定的字符串,aaa 用于捕获组。 + 量词将获取字符串的所有a,正则表达式引擎将逐个字符回溯,直到模式匹配。
    • @CasimiretHippolyte。哎呀。错过了那个量词现在在a,而不是aa
    【解决方案2】:

    + 量词表示“1 或更多”。 \1 指的是捕获的组,这与量词所指的相同。如此有效,它是在说“aa 组,1 次或多次,然后再进行一次”。与“2次或多次”相同。

    所以正则表达式可能会更清晰:/(aa){2,}/

    由于aaaaaaaa 组的三组,正则表达式匹配字符串。

    【讨论】:

    • 这并没有解释 如何 执行匹配(即回溯),这是 OP 所要求的。
    【解决方案3】:

    场景:

    aa           # the group is matched
    aaaa         # the group is repeated once, cause the + quantifier
    aaaaaa       # the group is repeated once again, always cause 
                 # the + quantifier (and because it is greedy and take all it can.)
                 # But since all the characters are eaten, and there is \1
                 # the pattern will fail.
    aaaa         # the regex engine must backtrack to try another way because of \1
    aaaaaa       # you are arrived! (the 2 last "a" are for the \1
    

    您可以使用禁止回溯的所有格量词 (++) 来验证此行为:

    (aa)++\1            # will never match
    

    【讨论】:

      猜你喜欢
      • 2019-08-02
      • 2015-04-07
      • 2018-10-05
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 2022-12-11
      • 1970-01-01
      • 2017-11-10
      相关资源
      最近更新 更多