我厌倦了总是试图猜测,()[]{}|
在使用许多正则表达式实现时是否应该转义' '等特殊字符。
它与Python,sed,grep,awk,Perl,重命名,Apache,find等不同。是否有任何规则集可以告诉我何时以及何时不应该转义特殊字符?它是否取决于正则表达式类型,例如PCRE,POSIX或扩展正则表达式?
我厌倦了总是试图猜测,()[]{}|
在使用许多正则表达式实现时是否应该转义' '等特殊字符。
它与Python,sed,grep,awk,Perl,重命名,Apache,find等不同。是否有任何规则集可以告诉我何时以及何时不应该转义特殊字符?它是否取决于正则表达式类型,例如PCRE,POSIX或扩展正则表达式?
Answers:
实际上,您必须转义哪些字符以及您必须避免转义哪些字符确实取决于您使用的正则表达式风格。
对于PCRE和大多数其他所谓的Perl兼容口味,请避免使用以下外部字符类:
.^$*+?()[{\|
以及这些内部字符类:
^-]\
对于POSIX扩展正则表达式(ERE),请转义这些外部字符类(与PCRE相同):
.^$*+?()[{\|
转义任何其他字符是POSIX ERE的错误。
在字符类中,反斜杠是POSIX正则表达式中的文字字符。您不能使用它来逃避任何事情。如果要包括字符类元字符作为文字,则必须使用“巧妙放置”。将^放置在字符类的开头以外的任何位置,将]放在开头,将-放在字符类的开头或结尾,以从字面上匹配这些字符,例如:
[]^-]
在POSIX基本正则表达式(BRE)中,这些是元字符,您需要对其进行转义以隐藏其含义:
.^$*[\
在BRE中转义括号和大括号给了它们特殊的含义,即它们在ERE中未转义的版本。一些实现(例如GNU)在转义时还赋予其他字符特殊的含义,例如\?。和+。转义除。^ $ *(){}以外的字符通常是BRE的错误。
在角色类中,BRE与ERE遵循相同的规则。
如果所有这些使您的头部旋转,请抓住RegexBuddy的副本。在“创建”选项卡上,单击“插入令牌”,然后单击“文字”。RegexBuddy将根据需要添加转义符。
/
在我提到的任何正则表达式形式中,它都不是元字符,因此正则表达式语法不需要将其转义。当一个正则表达式引述的编程语言文字,那么,语言的字符串或正则表达式格式规则可能要求/
或"
或'
进行转义,甚至可能需要`\`要倍加逃脱。
包括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兼容性可能会有所不同
任何地方: . ^ $ * + - ? ( ) [ ] { } \ |
包括awk,ed,egrep,emacs,GNUlib,grep,PHP(ereg),MySQL,Oracle,R,sed。
可以在更高版本中或通过使用扩展启用PCRE支持
ERE / awk / egrep / emacs
角色类别外:角色类别. ^ $ * + ? ( ) [ { } \ |
内:^ - [ ]
BRE / ed / grep / sed
字符类外:字符类. ^ $ * [ \
内:^ - [ ]
对于文字,请不要转义:+ ? ( ) { } |
对于标准正则表达式行为,请转义:\+ \? \( \) \{ \} \|
\xFF
] -
只需要在字符类中转义,但是为了简单起见,我将它们保留在一个列表中"(\")(/)(\\.)"
与/(")(\/)(\.)/
JavaScript中的相比)-
或]
可以在字符类之外进行转义。POSIX(BRE / ERE)在字符类中没有转义字符。Delphi的RTL中的正则表达式实际上是基于PCRE的。Python,Ruby和XML具有自己的风格,与POSIX风格更接近PCRE。
有时,列出的字符无法简单地转义。例如,使用反斜杠转义括号无法在sed中的替换字符串的左侧起作用,即
sed -e 's/foo\(bar/something_else/'
我倾向于只使用一个简单的字符类定义,所以上面的表达式变成
sed -e 's/foo[(]bar/something_else/'
我发现它适用于大多数正则表达式实现。
BTW字符类是漂亮的正则表达式组成部分,因此它们在大多数需要在正则表达式中转义字符的情况下都可以使用。
编辑:在下面的评论之后,我以为我要提到一个事实,当您查看正则表达式评估的行为时,还必须考虑有限状态自动机和非有限状态自动机之间的区别。
您可能想看一本“闪亮的书”,又称“有效Perl”(经过消毒的Amazon链接),特别是有关正则表达式的章节,以了解正则表达式引擎评估类型的不同之处。
并非全世界都是PCRE!
无论如何,与SNOBOL相比,regexp是如此笨拙!现在,这是一个有趣的编程课程!与Simula上的那个一起。
七十年代末在UNSW学习的乐趣啊!(-:
对于PHP,“在非字母数字前加“ \”来指定它代表自身总是安全的。” - http://php.net/manual/en/regexp.reference.escape.php。
除非它是“或”。
要在PHP中转义正则表达式模式变量(或部分变量),请使用preg_quote()
要准确地理解字符串所经过的上下文链,必须知道何时以及什么情况下无需进行尝试就可以逃脱。您将指定从最远端到最终目标的字符串,该目标是由regexp解析代码处理的内存。
请注意如何处理内存中的字符串:如果可以是代码内的纯字符串,也可以是输入到命令行的字符串,但是a可以是交互式命令行或在shell脚本文件中声明的命令行,或者在代码提到的内存变量中,或通过进一步评估的(字符串)参数,或包含通过任何封装动态生成的代码的字符串...
每个上下文都为某些字符分配了特殊功能。
当您想直接使用字符而不使用其特殊功能(对于上下文而言是本地的)时,对于这种情况,您必须对其进行转义,对于下一个上下文...这可能需要一些其他转义字符,可能还需要在前面的上下文中转义了。此外,可能还有字符编码之类的东西(最阴险的是utf-8,因为它看起来像ASCII的普通字符,但是即使终端根据其设置也可能会对其进行可选解释,因此其行为可能不同,然后是HTML的编码属性/ XML,有必要正确地了解该过程。
例如,以开头的命令行中的正则表达式perl -npe
需要转移到一组exec系统调用,这些文件以管道的形式连接到文件句柄,每个exec系统调用仅包含由(非转义)空格分隔的参数列表,以及可能的管道(|)和重定向(> N> N>&M),括号,*
和的交互式扩展?
,$(())
...(所有这些都是* sh使用的特殊字符,在下一个上下文中可能看起来会干扰正则表达式的字符,但是它们的评估顺序为:在命令行之前。命令行由a读取。作为bash / sh / csh / tcsh / zsh的程序,本质上是在双引号或单引号内进行转义比较简单,但是不必在命令行中用引号引起来,因为大多数空格必须以反斜杠作为前缀,并且引号是不必保留字符*和?的扩展功能,但是可以将其解析为与引号内不同的上下文,然后在评估命令行时,在内存中获得的regexp(与在命令行中写入的方式不同)将接受与之相同的处理将在源文件中。对于regexp,在方括号[]中包含字符集上下文,perl正则表达式可以用大量非字母数字字符(例如m //或m:/ better / for / path:...)引用。
您在其他答案中有关于字符的更多详细信息,这些字符非常特定于最终的正则表达式上下文。正如我提到的那样,您会发现带有尝试的regexp转义符,这可能是因为不同的上下文具有不同的字符集而混淆了您的尝试记忆(反斜杠通常是在这些不同的上下文中用于转义文字字符而不是其功能的字符) )。
https://perldoc.perl.org/perlre.html#Quoting-metacharacters和https://perldoc.perl.org/functions/quotemeta.html
在官方文档中,此类字符称为元字符。引用示例:
my $regex = quotemeta($string)
s/$regex/something/
对于Ionic(Typescript),您必须加倍斜线以使字符转义。例如(这是为了匹配一些特殊字符):
"^(?=.*[\\]\\[!¡\'=ªº\\-\\_ç@#$%^&*(),;\\.?\":{}|<>\+\\/])"
注意这个] [ - _ . /
字符。他们必须被大大削减。如果不这样做,您的代码中将出现类型错误。
escape()
”的功能,以允许使用任意字符串作为正则表达式部分。