【问题标题】:Is it an error to escape every metacharacter with PCREs and EREs?使用 PCRE 和 ERE 转义每个元字符是否错误?
【发布时间】:2012-12-02 12:32:57
【问题描述】:

在正则表达式中,某些字符只有在适当放置时才能获得元字符的特殊含义,否则保持其字面含义。例如,- 字符仅在放置在方括号表达式 [] 中并且在外部是文字短划线时才被视为元字符。

但就个人而言,我喜欢将元字符视为保留字符,并采用严格的规则来转义每个需要字面量的元字符。这节省了我一点时间,否则我会花在考虑元字符在正则表达式中的位置上。

但是,据我所知,转义这样的字符通常是 GNU BRE 的错误。而这个正则表达式

foo\-[0-9]+

在其\- 部分被 RegexBuddy 视为无效。此外,RegexBuddy 指示 GNU ERE(但不是 PCRE)的相同错误。另一方面,Ubuntu 上的 grep 不会将此正则表达式视为错误,并且从我的测试中它运行良好,即使 grep 应该默认使用 ERE。

因此,将 BRE 和 RegexBuddy 放在一边,仅考虑在当今许多系统和编程语言中使用的 PCRE 和 ERE,问题是习惯于转义每个可能的元字符以获取其字面意义可能是多么错误?

【问题讨论】:

    标签: regex pcre


    【解决方案1】:

    我只能在这里回答 PCRE。在 PCRE 中,您可以随心所欲地逃避,但不会有任何影响。引用PHP's PCRE documentation on escape sequences:

    [...] 如果 [a backslash] 后跟一个非字母数字字符,它会消除该字符可能具有的任何特殊含义。

    我会将“可能有”解释为“没有意义也没关系”。我用你给的例子测试了它,没有问题。


    不管使用何种正则表达式引擎,一般来说:

    我想提一下,虽然为了安全起见总是逃避一切似乎是个好主意,但您至少应该有意识地考虑一下可读性影响。无论如何,正则表达式往往会变得难以阅读,并且用不必要的反斜杠将它们弄乱并不能真正改善这一点。特别是,在字符类中,我只会转义字符类中的元字符(我个人甚至更喜欢将它们移动到不需要转义的特定位置,例如[a-zA-Z0-9_-],但是我可以看到有些人不喜欢那样)。这有一个很好的副作用。您可以使用字符类,作为(在我看来)更易于阅读的替代方法,用于转义在字符类之外但不在字符类内部的元字符的字符。所以你可以写[|]而不是\|或[.]而不是\.。在等宽字体中,这个单字符字符类构成了一个漂亮的正方形,很容易将其识别为单个元素,并且重要字符就在它的中心(而在\. 中,重要字符被移到了右边如果有意义的话,在“复合单个字符”中)。此外,如果涉及转义括号接近非转义括号,我发现转义字符类更具可读性:(\()(\)) 与 ([(])([)])。当然,这又是一个品味问题。但在为正则表达式设置转义约定时,值得考虑一下。

    【讨论】:

      【解决方案2】:

      您不是在问是否可以“转义每个元字符”,而是“转义每个我不确定它是否是元字符的字符”。听起来你只是想逃避所有不是字母或数字的东西。

      这不是功能错误,而是:

      • 它使代码更难阅读。字符越少越好。
      • 这让追随您的程序员想知道您为什么要不必要地转义字符,并花时间试图弄清楚您的代码有什么不同以及您要解决什么问题。
      • 当那个程序员最终发现你只是在逃避非元字符字符时,她会认为你是一个不称职的程序员。

      学习你的工具,学会正确使用它们,不要使用巫术来解决你缺乏知识的问题。

      【讨论】:

        【解决方案3】:

        我不知道 POSIX 正则表达式或 PCRE,但在 Perl 中,每个反斜杠非单词字符都保证与自身匹配。详情请见perldoc -f quotemeta。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-21
          • 1970-01-01
          • 1970-01-01
          • 2010-10-21
          • 2012-02-12
          • 2011-08-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多