什么特殊字符必须在正则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()