必须在正则表达式中转义哪些特殊字符?

时间:2008-12-29 23:32:05

标签: regex

我厌倦了总是试图猜测,如果我在使用许多regexp实现时应该转换像'()[]{}|'等特殊字符。

它与例如Python,sed,grep,awk,Perl,rename,Apache,find等不同。 是否有任何规则集告诉我何时应该,何时不应该逃避特殊字符?它是否依赖于正则表达式类型,如PCRE,POSIX或扩展的正则表达式?

12 个答案:

答案 0 :(得分:333)

您必须使用哪些角色,哪些角色无法逃脱,取决于您正在使用的正则表达式。

对于PCRE以及大多数其他所谓的Perl兼容版本,请忽略这些外部角色类:

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

以及这些内部角色类:

^-]\

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

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

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

在字符类内部,反斜杠是POSIX正则表达式中的文字字符。你不能用它来逃避任何事情。如果要将字符类元字符包含为文字,则必须使用“巧妙放置”。把^除了起点之外的任何地方,把]放在开头,然后把 - 在字符类的开头或结尾处按字面意思匹配,例如:

[]^-]

在POSIX基本正则表达式(BRE)中,这些是元字符,您需要转义它们以抑制其含义:

.^$*[\

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

在内部角色类中,BRE遵循与ERE相同的规则。

如果所有这些让你头晕,请抓取RegexBuddy的副本。在“创建”选项卡上,单击“插入标记”,然后单击“文字”。 RegexBuddy将根据需要添加转义。

答案 1 :(得分:56)

Modern RegEx Flavors(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兼容性可能有所不同

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

Legacy RegEx Flavors(BRE / ERE)

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

<强> ERE / AWK / egrep的/ emacs的

在角色类之外:. ^ $ * + ? ( ) [ { } \ |
在角色类中:^ - [ ]

<强> BRE / ED / grep的/ SED

在角色类之外:. ^ $ * [ \
在角色类中:^ - [ ]
对于文字,请不要逃避:+ ? ( ) { } |
对于标准正则表达式行为,请转义:\+ \? \( \) \{ \} \|

备注

  • 如果对特定字符不确定,可以像\xFF
  • 一样进行转义
  • 使用反斜杠
  • 无法转义字母数字字符
  • 可以使用PCRE中的反斜杠转义任意符号,但不能转发BRE / ERE(必须在必要时转义它们)。对于PCRE ] -,只需要在字符类中进行转义,但为了简单起见,我将它们保存在单个列表中
  • 引用的表达式字符串也必须包含转义的周围引号字符,并且通常使用反斜杠加倍(例如JavaScript中的"(\")(/)(\\.)"/(")(\/)(\.)/
  • 除了转义之外,不同的正则表达式实现可以支持不同的修饰符,字符类,锚点,量词和其他功能。有关详情,请查看regular-expressions.info,或使用regex101.com来测试您的表情

答案 2 :(得分:22)

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

但是,保留Regular Expression Tools Page或此Regular Expression Cheatsheet这样的网页可以帮助您快速筛选出来。

答案 3 :(得分:5)

POSIX识别正则表达式的多种变体 - 基本正则表达式(BRE)和扩展正则表达式(ERE)。即便如此,由于POSIX标准化的实用程序的历史实现,还有一些怪癖。

关于何时使用哪种符号,甚至是给定命令使用哪种符号,没有简单的规则。

查看Jeff Friedl的Mastering Regular Expressions书。

答案 4 :(得分:4)

不幸的是,像(和\(在Emacs风格的正则表达式和大多数其他样式之间交换)的含义。所以如果你试图逃避这些,你可能会做你想要的反面。

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

答案 5 :(得分:4)

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

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

我倾向于使用简单的字符类定义,因此上面的表达式变为

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

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

BTW字符类是非常普通的regexp组件,所以它们往往适用于需要在regexp中转义字符的大多数情况。

编辑:在下面的评论之后,我想提一下,在查看regexp的行为时,你还必须考虑有限状态自动机和非有限状态自动机之间的区别这一事实。评价。

您可能希望查看“闪亮的球书”又名有效Perl(sanitised Amazon link),特别是关于正则表达式的章节,以了解正则表达式引擎评估类型的差异。

并非所有的世界都是PCRE!

无论如何,与SNOBOL相比,regexp是如此笨重!现在 是一个有趣的编程课程!与Simula上的那个一起。

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

答案 6 :(得分:3)

真的,没有。有大约半个不同的正则表达式语法;它们似乎总体上归结为Perl,EMACS / GNU和AT&amp; T,但我也总是感到惊讶。

答案 7 :(得分:2)

对于PHP,“在非字母数字之前加上”\“以指定它代表自己是安全的。” - http://php.net/manual/en/regexp.reference.escape.php

除非它是“或”。:/

要在PHP中转义正则表达式模式变量(或部分变量),请使用preg_quote()

答案 8 :(得分:2)

要准确地了解字符串所经过的上下文链,必须知道何时以及不进行尝试就转义什么。您将指定从最远端到最终目的地的字符串,该字符串是由regexp解析代码处理的内存。

请注意如何处理内存中的字符串:如果可以是代码内的纯字符串,也可以是输入到命令行的字符串,但是a可以是交互式命令行或在Shell脚本中声明的命令行文件,或代码中提到的内存变量中,或通过进一步评估的(字符串)参数,或包含通过任何封装动态生成的代码的字符串...

每个上下文都分配了具有特殊功能的字符。

当您想直接使用字符而不使用其特殊功能(对于上下文是局部的)时,对于这种情况,您必须对其进行转义,对于下一个上下文...这可能需要其他转义字符,这可能另外需要在前面的上下文中转义。 此外,可能还有字符编码之类的东西(最阴险的是utf-8,因为它看起来像ASCII的常见字符,但是即使终端根据其设置也可能会对其进行解释,因此它的行为可能不同,然后是HTML的编码属性/ XML,有必要正确地了解该过程。

例如需要将以perl -npe开头的命令行中的正则表达式转移到一组 exec 系统调用中,该系统调用以文件处理的管道方式进行连接,每个此exec系统调用仅包含一个列表。由(非转义)空间分隔的参数,可能还有管道(|)和重定向(> N> N>&M),括号,*?$(())的交互式扩展...(所有这些都是* sh使用的特殊字符,在下一个上下文中可能看起来会干扰正则表达式的字符,但它们的评估顺序为:在命令行之前。命令行由a读取。作为bash / sh / csh / tcsh / zsh的程序,本质上是在双引号或单引号内进行转义比较简单,但是不必在命令行中用引号引起来,因为大多数空格必须以反斜杠作为前缀,并且引号是不必保留字符*和?的扩展功能,但是可以将其解析为与引号内不同的上下文。评估第nd行在内存中获得的正则表达式(而不是在命令行中写入)接受与源文件中相同的处理。 对于正则表达式,在方括号[]中有字符集上下文,perl正则表达式可以用大量非字母数字字符(例如m //或m:/ better / for / path:...)引用。

您在其他答案中有关于字符的更多详细信息,这些信息非常特定于最终的正则表达式上下文。正如我提到的那样,您会发现带有尝试的regexp转义,这可能是因为不同的上下文具有不同的字符集而混淆了您的尝试记忆(反斜杠通常是在这些不同的上下文中用于转义文字字符而不是其功能的字符) )。

答案 9 :(得分:0)

https://perldoc.perl.org/perlre.html#Quoting-metacharactershttps://perldoc.perl.org/functions/quotemeta.html

在官方文档中,引用元字符:

select id, max(data1),sum(amount)
from tablename
group by id

答案 10 :(得分:0)

对于Ionic(打字稿),您必须加倍斜杠才能对字符进行换码。 例如(这是为了匹配一些特殊字符):

"^(?=.*[\\]\\[!¡\'=ªº\\-\\_ç@#$%^&*(),;\\.?\":{}|<>\+\\/])"

请注意此] [ - _ . /个字符。他们必须被大大削减。如果您不这样做,那么您的代码中将会出现类型错误。

答案 11 :(得分:0)

也许是一个旧线程,但是此代码对于想要不使用正则表达式创建的访问者可能有用

def listToString(s):  
    
    # initialize an empty string 
    str1 = "" 
    
    # return string   
    return (str1.join(s))


r = "Hello! How are you? *Smiling_Face* *Heart* erwer"
r1 = list(r)
i = 0
r2 = list()
start = True

for string in r1:
    if string == "*":
        if(start):
            start = False
        else:
            start = True
    else:
        if(start):
            r2.append(string)
        else:
            print("skipped" + string)
            
 
print(listToString(r2))