【问题标题】:removing redundancy from regex with multiple possible delimiters使用多个可能的分隔符从正则表达式中删除冗余
【发布时间】:2012-10-05 00:47:13
【问题描述】:

我有一个正则表达式,其中相同的匹配条件可以应用于多个分隔符。 []、() 和 <> 均有效。例如,它看起来像这样:

\[.\]|\(.\)|<.>

有没有办法从上面的正则表达式中删除冗余?分隔符内的匹配条件始终相同,但分隔符本身可能不同。

【问题讨论】:

    标签: regex pcre


    【解决方案1】:

    我猜你问是因为

    [[(<].[])>]
    

    不够准确,原因很明显。

    回答“不,没有办法”总是很危险的,因为很难确定一个人已经检查了所有可能的方法。在这种情况下,人们必须经常拿出可靠的证据来回答。

    我不确定这是一个足够强大的证明,甚至根本不是“证明”,但考虑一下这个(伪)信息论观点:

    1. PCRE 引擎本身不知道字符对[]、() 和&lt;&gt; 之间的任何关系。因此,表达式本身必须包含该信息,即要求至少有六个字符[]()&lt;&gt;。

    2. 不仅如此,出于同样的原因,表达式本身必须至少定义两个配对(隐含第三个)。我不确定如何证明两个交替运算符 (|) 是你能做的最好的,但我的意思是,即使有 更紧凑的方法,你也会保存最多一个字符,因为至少需要一位来表示“配对存在!”

    3. 元字符的转义只能通过 []() 可以出现在字符类中而不被转义的事实来压缩,但首先,这并不是真正的“消除冗余”是“语法上的幸运情况”,其次,您仍然需要为所述字符类的定义添加两个字符:[]。

    4. 因此,我相信即使从理论角度来看,如果我对正则表达式引擎无法知道的假设是正确的,那么最多可以保存 em> 您已经提供的正则表达式中的三个字符:\[.\]|\(.\)|&lt;.&gt;。

    我热切期待正则表达式大师的纠正!

    【讨论】:

      【解决方案2】:

      如果你真的在使用PCRE library(例如通过 PHP),你可以使用 DEFINE 组来创建一个子例程,如下所示:

      '~(?(DEFINE)(?<content>\w+))(?:<(?&content)>|\[(?&content)\]|\((?&content)\))~'
      

      ...或更易读:

      (?(DEFINE)(?<content>\w+))
      (?:
        <(?&content)>
        |
        \[(?&content)\]
        |
        \((?&content)\)
      )
      

      这是 PHP 中的 demo。它也应该在 Perl 中工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-04
        • 1970-01-01
        • 2016-02-07
        相关资源
        最近更新 更多