首页 文章

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

提问于
浏览
341

我厌倦了总是试图猜测,如果我在使用许多regexp实现时应该逃避像' ()[]{}| '这样的特殊字符 .

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

8 回答

  • 1

    您必须使用哪些角色以及哪些角色确实无法逃脱取决于您正在使用的正则表达式 .

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

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

    以及这些内部角色类:

    ^-]\
    

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

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

    使用POSIX ERE时,转义任何其他字符都是错误的 .

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

    []^-]
    

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

    .^$*
    

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

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

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

  • 4

    现代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兼容性可能有所不同

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


    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来测试您的表达式

  • 3

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

    但是,保持像Regular Expression Tools Page或_2573203这样的页面可以帮助您快速筛选出来 .

  • 325

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

    什么时候使用哪种表示法,甚至是给定命令使用哪种表示法都没有简单的规则 .

    查看Jeff Friedl的Mastering Regular Expressions书 .

  • 2

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

    所以你真的要知道你是什么风格试图引用 .

  • 53

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

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

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

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

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

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

    Edit: 在下面的评论之后,我想提一下,在查看正则表达式评估的行为时,你还必须考虑有限状态自动机和非有限状态自动机之间的区别 .

    您可能希望查看"the shiny ball book"又名有效Perl(sanitised Amazon link),特别是有关正则表达式的章节,以了解正则表达式引擎评估类型的差异 .

    并非所有的世界都是PCRE!

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

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

  • 21

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

  • 3

    对于PHP,"it is always safe to precede a non-alphanumeric with " \ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    除非它是“或” . :/

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

相关问题