什么特殊字符必须在正则expression式中转义?

我厌倦了总是试图猜测,如果我应该逃避特殊字符,如' ()[]{}| '等使用正则expression式的很多实现。

例如,Python,sed,grep,awk,Perl,rename,Apache,find等等是不同的。 有什么规则可以告诉我应该什么时候,什么时候不应该逃避特殊字符? 它是否依赖于正则expression式types,如PCRE,POSIX或扩展正则expression式?

你必须确定哪些字符以及哪些字符不能逃脱,这取决于你正在使用的正则expression式。

对于PCRE和大多数其他所谓的Perl兼容风格,转义这些外部字符类:

 .^$*+?()[{\| 

和这些里面的字符类:

 ^-]\ 

对于POSIX扩展正则expression式(ERE),转义这些外部字符类(与PCRE相同):

 .^$*+?()[{\| 

转义任何其他字符是POSIX ERE错误。

在字符类内部,反斜杠是POSIX正则expression式中的文字字符。 你不能用它来逃避任何事情。 如果要将字符类元字符包含为文字,则必须使用“巧妙放置”。 把^放在开头的任何地方,在开始处, – 在字符类的开始或结尾,按字面顺序匹配,例如:

 []^-] 

在POSIX的基本正则expression式(BRE)中,这些元字符是您需要转义来压制其含义的元字符:

 .^$* 

在BRE中转义括号和大括号赋予它们在ERE中非转义版本的特殊含义。 有些实现(例如GNU)在转义时也赋予其他字符特殊的含义,比如\? 和+。 转义除。^ $ *(){}之外的字符通常是BRE错误。

在字符类内部,BRE遵循与ERE相同的规则。

如果所有这一切都让你头晕目眩 , 那就拿一份RegexBuddy吧 。 在“创build”选项卡上,单击“插入令牌”,然后单击“文字”。 RegexBuddy会根据需要添加转义。

现代RegEx香料(PCRE)

包括C,C ++,Delphi,EditPad,Java,JavaScript,Perl,PHP(preg),PostgreSQL,PowerGREP,PowerShell,Python,REALbasic,Real Studio,Ruby,TCL,VB.Net,VBScript,wxWidgets,XML Schema,Xojo, XRegExp。
PCRE兼容性可能有所不同

任何地方: . ^ $ * + - ? ( ) [ ] { } \ | . ^ $ * + - ? ( ) [ ] { } \ |


传统RegEx香料(BRE / ERE)

包括awk,ed,egrep,emacs,GNUlib,grep,PHP(ereg),MySQL,Oracle,R,sed。
PCRE支持可能会在更高版本或使用扩展启用

ERE / AWK / egrep的/ emacs的

在angular色类之外: . ^ $ * + ? ( ) [ { } \ | . ^ $ * + ? ( ) [ { } \ |
在一个字符类里面: ^ - [ ]

BRE / ED / grep的/ SED

在angular色类之外: . ^ $ * [ \ . ^ $ * [ \
在一个字符类里面: ^ - [ ]
对于文字,不要逃避: + ? ( ) { } | + ? ( ) { } |
对于标准的正则expression式行为,转义: \+ \? \( \) \{ \} \| \+ \? \( \) \{ \} \|


笔记

  • 如果不确定一个特定的字符,它可以像\xFF那样转义
  • 字母数字字符不能用反斜线转义
  • 任意符号可以用PCRE中的反斜杠转义,但不能用BRE / ERE(只有在需要时才能转义)。 对于PCRE ] -只需要在字符类中转义,但是为了简单起见,我将它们保存在一个列表中
  • 引用的expression式string还必须将周围的引号字符转义出来,并且反斜杠通常加倍(如"(\")(/)(\\.)"/(")(\/)(\.)/ in JavaScript的)
  • 除了转义,不同的正则expression式实现可能支持不同的修饰符,字符类,锚点,量词和其他function。 有关更多详细信息,请查看regular-expressions.info ,或者使用regex101.com来实时testing您的expression式

不幸的是,实际上没有一组转义码,因为它根据您使用的语言而有所不同。

但是,像正则expression式工具页或这个正则expression式Cheatsheet保持一个页面可以帮助你快速过滤掉很多东西。

POSIX识别正则expression式的多种变体 – 基本正则expression式(BRE)和扩展正则expression式(ERE)。 即使如此,由于POSIX标准化的公用事业的历史实施,也存在一些怪癖。

什么时候使用哪种符号,甚至给定的命令使用哪种符号,都不是一个简单的规则。

查看Jeff Friedl的Mastering Regular Expressions书籍。

不幸的是,像(和)之类的东西的意思是在Emacs风格的正则expression式和大多数其他风格之间交换,所以如果你试图逃避这些东西,你可能会做出与你想要的相反的东西。

所以你真的要知道你想引用什么风格。

有时,您所列出的字符无法进行简单的转义。 例如,使用反斜杠转义括号不会在sed中的replacestring的左侧工作,即

 sed -e 's/foo\(bar/something_else/' 

我倾向于只使用一个简单的字符类定义,所以上面的expression式就变成了

 sed -e 's/foo[(]bar/something_else/' 

我发现它适用于大多数正则expression式实现。

BTW字符类是相当香草正则expression式组件,所以他们倾向于工作在大多数情况下,你需要在正则expression式逃脱字符。

编辑:在下面的评论之后,我想提到一个事实,那就是在考察正则expression式评估的行为时,你还必须考虑有限状态自动机和非有限状态自动机之间的区别。

您可能会喜欢看“有光泽的球书”,即有效的Perl( 消毒的亚马逊链接 ),特别是正则expression式的章节,以获得正则expression式引擎评估types的差异。

不是所有的世界都是PCRE!

无论如何,与SNOBOL相比,正则expression式非常笨重! 现在是一个有趣的编程课程! 与Simula一起 。

70年代后期在新南威尔士大学学习的乐趣! ( – :

真的,没有。 大约有五十亿个不同的正则expression式语法; 他们似乎一般都会涉及到Perl,EMACS / GNU和AT&T,但我也一直很惊讶。

对于PHP来说,“在非字母数字之前加上”\“来指定它代表它本身总是安全的。” – http://php.net/manual/en/regexp.reference.escape.php

除非是“或”。:/

要在PHP中转义正则expression式模式variables(或部分variables),使用preg_quote()