用PCRE和ERE逃避每个元字符是错误的吗?

时间:2012-12-02 12:32:58

标签: regex pcre

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

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

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

foo\-[0-9]+
RegexBuddy在其\-部分中将

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

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

3 个答案:

答案 0 :(得分:3)

我只能在这里回答PCRE。在PCRE中你可以随心所欲地逃脱,它不会有所作为。引用PHP's PCRE documentation on escape sequences

  

[...]如果[反斜杠]后跟一个非字母数字字符,它会消除角色可能具有的任何特殊含义。

我会解释“可能拥有”,“如果它没有意义就没关系”。我用你给出的例子测试了它,没有问题。


一般情况下,无论正在使用的正则表达式引擎如何:

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

答案 1 :(得分:2)

你不是在问你是否可以“逃避每一个元素”,而是“逃避每一个我不确定它是否属于元字符的角色。”听起来你只想逃避一切不是字母或数字的东西。

这不是功能错误,而是:

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

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

答案 2 :(得分:0)

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