【问题标题】:RegEx Backreferences正则表达式反向引用
【发布时间】:2010-01-14 01:57:13
【问题描述】:

具有以下正则表达式:

([a-z])([0-9])\1

匹配a5a,有什么方法可以匹配a5ba5ca5d等等?


编辑:好的,我知道我可以使用([a-z])([0-9])([a-z]),但我有一个非常长且复杂的正则表达式(匹配 sub-sub-sub-...-域匹配 IPv4 地址)将真正受益于上述行为。这是否可以通过反向引用或其他任何方式实现?


Anon. answer是我所需要的,但似乎是错误的。

【问题讨论】:

    标签: php regex pcre backreference


    【解决方案1】:

    答案是没有反向引用

    反向引用意味着匹配之前匹配的值。这并不意味着匹配前面的表达式。但是,如果您的语言允许,您可以在编译之前将字符串中的变量替换为表达式。

    Tcl:

    set exp1 "([a-z])"
    regexp "${exp1}([0-9])${exp1}+" $string
    

    Javascript:

    var exp1 = '([a-z])';
    var regexp = new RegExp(exp1 + '([0-9])' + exp1 + '+');
    string.match(regexp);
    

    Perl:

    my $exp1 = '([a-z])';
    $string =~ /${exp1}([0-9])${exp1}+/;
    

    【讨论】:

      【解决方案2】:

      如果第二个字母独立于第一个字母,您就不需要反向引用,对吧?

      ([a-z])([0-9])([a-z])+
      

      编辑

      如果你只是不想一遍又一遍地重复最后一部分,那么:

      ([a-z])([0-9])([a-z])
      

      只是去掉'+'。

      【讨论】:

      • 不,我想要你提供的第一个正则表达式 ([a-z])([0-9])([a-z])+ 的效果,但不必一遍又一遍地重复最后一部分。
      【解决方案3】:

      正则表达式中反向引用的全部意义在于匹配与指示的子表达式相同的内容,因此无法禁用该行为。

      要获得您想要的行为,以便以后能够重用正则表达式的一部分,您只需在单独的字符串中定义您希望重用的正则表达式部分,并且(取决于您使用的语言)重新工作)使用字符串插值或连接从片段构建正则表达式。

      例如,在 Ruby 中:

      >> letter = '([a-z])'
      => "([a-z])"
      >> /#{letter}([0-9])#{letter}+/ =~ "a5b"
      => 0
      >> /#{letter}([0-9])#{letter}+/ =~ "a51"
      => nil
      

      或者在 JavaScript 中:

      var letter = '([a-z])';
      var re = new RegExp(letter + '([0-9])' + letter + '+');
      "a5b".match(re)
      

      【讨论】:

        【解决方案4】:

        我怀疑您想要类似于 Perl (?PARNO) 构造的东西(它不仅仅是用于递归;)。

        /([a-z])([0-9])(?1)+/
        

        将匹配您想要的 - 对第一个捕获组的任何更改都将反映在 (?1) 匹配的内容中。

        【讨论】:

        • 似乎是我正在寻找的东西,但是您提供的正则表达式在 RegexBuddy 中给了我错误(在 PCRE 和 Perl 模式下)。
        • 正则表达式的 (?1) 部分在 Perl 模式下的 RegexBuddy 中给了我以下错误:错误字符(可能是不完整的正则表达式标记或未转义的元字符),无论如何,谢谢。 =)
        • 那么我猜 RegexBuddy 不处理 Perl 正则表达式的那个特性。在 Perl 中尝试一下,你会发现它可以工作。
        • 我不怀疑你,但我实际上需要这个正则表达式用于 PHP 项目。 =\ 不过,很高兴知道。
        • 现在尝试一下,它也适用于我的 PHP 版本。在关闭它之前,在现实世界中试一试,而不仅仅是在 RegexBuddy 中试一试。
        【解决方案5】:

        我没有听懂你的问题?

        [a-z][0-9][a-z] Exactly 1
        [a-z][0-9][a-z]? One or 0
        [a-z][0-9][a-z]+ 1 or more
        [a-z][0-9][a-z]* 0 or more
        

        【讨论】:

          【解决方案6】:

          反向引用用于从正则表达式的早期检索数据并在以后使用它。它们不是用来解决风格问题的。带有反向引用的正则表达式不会像没有反向引用的那样起作用。您可能只需要习惯正则表达式的重复和丑陋。

          也许可以试试 Python,它可以很容易地从较小的块构建正则表达式。不清楚你是否可以改变你的环境……你很幸运一开始就有反向引用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-04-01
            • 1970-01-01
            • 2010-11-28
            • 2018-07-13
            • 1970-01-01
            • 2019-03-25
            • 2012-03-01
            相关资源
            最近更新 更多