正则表达式中必须转义的特殊字符是什么?

468

我已经厌倦了在使用许多正则表达式实现时,总是试图猜测是否应该转义特殊字符如'()[]{}|'等。

例如Python、sed、grep、awk、Perl、rename、Apache、find等都不同。是否有规则集可以告诉我何时应该转义特殊字符,何时不应该转义? 是否取决于正则表达式类型,如PCRE、POSIX或扩展正则表达式?


5
好的正则表达式库拥有像“escape()”这样的函数,允许使用任意字符串作为正则表达式的一部分。 - ivan_pozdeev
2
你可以使用在线的正则表达式检查工具,例如http://gskinner.com/RegExr/(它是免费的)。 (输入正则表达式后,将鼠标悬停在其上即可查看) - hexicle
2
转义所有非字母数字字符。句号。 - salmatron
2
这个问题已被添加到Stack Overflow 正则表达式 FAQ中的“其他”分类下。 - aliteralmind
1
此问题已添加到Stack Overflow正则表达式FAQ,位于“转义序列”下。 - aliteralmind
显示剩余3条评论
13个回答

1

使用 Raku(前身为 Perl_6)

可行的方法(对于非字母数字字符,除了下划线,需要加上反斜杠或引号):

~$ raku -e 'say $/ if "#.*?" ~~ m/  \# \. \* \?  /; #works fine'#.*?」

根据Damian Conway的pdf/talk "Everything You Know About Regexes Is Wrong",正则表达式语言有六种不同的风格。Raku是标准Perl(5)/PCRE正则表达式的重要改进(约15年)。

在这15年中,Perl_6 / Raku语言专家决定所有非字母数字字符(除下划线外)都应该被保留为正则表达式元字符,即使没有现有的用法。为了表示非字母数字字符(除下划线外)作为文字,需要使用反斜杠或转义它们。

因此,如果找到与文字#.*?序列匹配的内容,则上述示例将打印$/匹配变量。如果不这样做,将会发生以下情况:#被解释为注释的开始,.点被解释为任何字符(包括空格),*星号被解释为零个或多个量词符,?问号被解释为零个或一个量词符或吝啬(即非贪婪)量词修饰符(取决于上下文):

错误:

~$ ~$ raku -e 'say $/ if "#.*?" ~~ m/  # . * ?  /; #ERROR!'
===SORRY!===
Regex not terminated.
at -e:1
------> y $/ if "#.*?" ~~ m/ # . * ?  /; #ERROR!⏏<EOL>
Regex not terminated.
at -e:1
------> y $/ if "#.*?" ~~ m/ # . * ?  /; #ERROR!⏏<EOL>
Couldn't find terminator / (corresponding / was at line 1)
at -e:1
------> y $/ if "#.*?" ~~ m/ # . * ?  /; #ERROR!⏏<EOL>
    expecting any of:
        /

https://docs.raku.org/language/regexes
https://raku.org/


1
为了避免担心使用哪个正则表达式变体和所有特定的怪癖,只需使用此通用函数,它涵盖了除BRE(除非它们具有元字符的Unicode多字节字符)之外的每个正则表达式变体:
jot -s '' -c - 32 126 | 
mawk '
function ___(__,_) {
    return substr(_="", 
    gsub("[][!-/_\140:-@{-~]","[&]",__),
    gsub("["(_="\\\\")"^]",_ "&",__))__ 

} ($++NF = ___($!_))^_'
 !"#$%&'()*+,-./0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
`abcdefghijklmnopqrstuvwxyz{|}~
    [!]["][#][$][%][&]['][(][)][*][+][,][-][.][/]
  0  1  2  3  4  5  6  7  8  9 [:][;][<][=][>][?]
 [@] ABCDEFGHIJKLMNOPQRSTUVWXYZ   [[]\\ []]\^ [_]
 [`] abcdefghijklmnopqrstuvwxyz   [{][|][}][~]

方括号更易处理,因为没有触发“转义过多”的警告信息的风险,例如:

function ____(_) {
    return substr("", gsub("[[:punct:]]","\\\\&",_))_ 
} 

                     \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/ 0123456789\:\;\<\=\>\?
\@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^\_\`abcdefghijklmnopqrstuvwxyz \{\|\}\~

gawk: cmd. line:1: warning: regexp escape sequence `\!' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\"' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\#' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\%' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\&' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\,' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\:' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\;' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\=' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\@' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\_' is not a known regexp operator
gawk: cmd. line:1: warning: regexp escape sequence `\~' is not a known regexp operator

0
在Ionic (Typescript)中,您需要双斜杠来转义字符。例如(这是为了匹配一些特殊字符):
"^(?=.*[\\]\\[!¡\'=ªº\\-\\_ç@#$%^&*(),;\\.?\":{}|<>\+\\/])"

请注意这些字符] [ - _ . /,它们必须加上双斜杠。如果不这样做,你的代码会出现类型错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接