1

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

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

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

foo\-[0-9]+

\-RegexBuddy认为其本身无效。此外,RegexBuddy 指示 GNU ERE(但不是 PCRE)的相同错误。另一方面,grep在 Ubuntu 上不会将此正则表达式视为错误,并且从我的测试中可以正常工作,即使grep默认情况下应该使用 ERE。

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

4

3 回答 3

3

我只能在这里回答 PCRE。在 PCRE 中,您可以随心所欲地逃避,但不会有任何影响。引用PHP 的关于转义序列的 PCRE 文档

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

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


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

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

于 2012-12-02T12:44:33.077 回答
2

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

这不是功能错误,而是:

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

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

于 2012-12-02T15:37:17.953 回答
0

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

于 2012-12-02T12:45:47.727 回答