代码之家  ›  专栏  ›  技术社区  ›  Igor Katson

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

  •  337
  • Igor Katson  · 技术社区  · 16 年前

    我已经厌倦了总是试图猜测,如果我应该逃避像' ()[]{}| '等。在使用许多regexp实现时。

    它与诸如python、sed、grep、awk、perl、rename、apache、find等不同。 有没有规则集可以告诉我什么时候应该转义特殊字符,什么时候不应该转义特殊字符?它是否依赖于regexp类型,如pcre、posix或扩展regexps?

    8 回复  |  直到 7 年前
        1
  •  321
  •   Jan Goyvaerts    11 年前

    你必须使用哪些字符,哪些字符不能转义,这取决于你所使用的regex风格。

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

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

    这些内部字符类:

    ^-]\
    

    对于POSIX扩展regex(ere),转义这些外部字符类(与pcre相同):

    ^ $*+?[]({)
    

    转义任何其他字符都是posix-ere的错误。

    在字符类中,反斜杠是POSIX正则表达式中的一个文本字符。你不能用它来逃避任何事情。如果要将字符类元字符包含为文本,则必须使用“巧妙放置”。将^放在字符类的开头、开头]和开头或结尾以外的任何位置,以逐字匹配这些字符,例如:

    []^-]
    

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

    .^$*
    

    BRES中的转义圆括号和花括号赋予了它们在ERES中的特殊含义。有些实现(例如GNU)在转义时也给其他字符赋予了特殊的含义,例如\?+。转义除^$*()以外的字符通常是BRES的错误。

    在字符类中,bres遵循与eres相同的规则。

    如果所有这些都让你头昏眼花,那就拿一份 RegexBuddy . 在“创建”选项卡上,单击“插入标记”,然后单击“文字”。RegexBuddy将根据需要添加转义。

        2
  •  49
  •   Beejor    7 年前

    现代Regex香精(PCRE)

    包括C、C++、Delphi、EddiPad、Java、JavaScript、Perl、PHP(PREG)、PostgreSQL、PowerGREP、PerfS壳、Python、REALbasic、RealStudio、Ruby、TCL、VB.NET、VBScript、WxWIDGet、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公司

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

    BRE/ED/GRIP/SED

    字符类之外: . ^ $ * [ \
    在字符类中: [-]
    对于文字,不要转义: + ? ( ) { } |
    对于标准regex行为,转义: \+ \? \( \) \{ \} \|


    笔记

    • 如果不确定某个特定的字符,可以像这样进行转义 \xFF
    • 字母数字字符不能用反斜杠转义
    • 任意符号可以在PCRE中用反斜杠转义,但不能用bre/ere转义(只有在需要时才能转义)。对于PCRE ] - 只需要在字符类中进行转义,但为了简单起见,我将它们保存在一个列表中。
    • 带引号的表达式字符串还必须对周围的引号字符进行转义,并且通常将反斜杠折叠起来(如 "(\")(/)(\\.)" 对战 /(")(\/)(\.)/ 在JavaScript中)
    • 除了转义,不同的regex实现可能支持不同的修饰符、字符类、锚、量词和其他特性。有关详细信息,请查看 regular-expressions.info 或使用 regex101.com 现场测试你的表情
        3
  •  21
  •   Dillie-O    16 年前

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

    但是,保持像 Regular Expression Tools Page 或者这个 Regular Expression Cheatsheet 能帮你快速过滤掉很多东西。

        4
  •  4
  •   Jonathan Leffler vy32    16 年前

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

    对于何时使用哪个符号,甚至给定命令使用哪个符号,没有一个简单的规则。

    看看Jeff Friedl的 Mastering Regular Expressions 书。

        5
  •  3
  •   Darron    16 年前

    不幸的是,诸如(和)之类的内容的含义在Emacs样式的正则表达式和大多数其他样式之间交换。所以,如果你试图逃避这些,你可能会做与你想做的相反的事情。

    所以你必须知道你要引用的是什么风格。

        6
  •  3
  •   vaxquis user2577497    7 年前

    有时,对于您列出的字符,简单的转义是不可能的。例如,在sed中,使用反斜杠来转义括号在替换字符串的左侧不起作用,即

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

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

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

    我发现它适用于大多数regexp实现。

    btw字符类是非常普通的regexp组件,因此它们在大多数情况下都可以工作,在regexp中需要转义字符。

    编辑: 在下面的注释之后,我想我会提到一个事实,即在查看regexp评估的行为时,您还必须考虑有限状态自动机和非有限状态自动机之间的区别。

    你可以看看“闪亮的球书”,也就是有效的Perl。( sanitised Amazon link ,特别是关于正则表达式的章节,了解regexp引擎计算类型中的差异。

    不是所有人都是PCRE!

    总之,与 SNOBOL !现在 那个 是一门有趣的编程课程!和上面的那个一起 Simula .

    啊,70年代末在新南威尔士大学学习的乐趣!(-)

        7
  •  2
  •   Charlie Martin    16 年前

    实际上,没有。大约有五千多种不同的regex语法;它们似乎归结为perl、emacs/gnu和a t&t一般来说,但我也总是感到惊讶。

        8
  •  1
  •   zylstra    11 年前

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

    除非是“或”。:

    要在PHP中转义regex模式变量(或部分变量),请使用preg_quote()。