一般来说,正则表达式中哪些字符需要转义?
例如,以下内容在语法上不正确:
echo '[]' | grep '[]'
grep: Unmatched [ or [^
然而,这是语法正确:
echo '[]' | grep '\[]'
[]
是否有任何文档说明在正则表达式中哪些字符应该转义,哪些不应该转义?
答案1
正则表达式有多种类型,特殊字符集取决于特定类型。其中一些描述如下。在所有情况下,特殊字符都通过反斜杠转义\
。例如,为了匹配[
你写的\[
。或者,可以通过将字符(除了^
)一一括在方括号中来转义,例如[[]
。
在某些上下文中特殊的字符(例如^
(子)表达式开头的特殊字符)可以在所有上下文中转义。
正如其他人所写:在 shell 中,如果您没有将表达式括在单引号之间,则必须在已转义的正则表达式中另外转义 shell 的特殊字符。示例:您可以在 Bourne 兼容的 shell(如 bash)中'\['
编写\\[
(或者:"\["
或),但这是另一个故事了。"\\["
基本正则表达式 (BRE)
- POSIX:基本正则表达式
- 命令:
grep
,sed
- 特殊字符:
.[\
- 在某些情况下特别:
*^$
- 转义字符串:
"$(printf '%s' "$string" | sed 's/[.[\*^$]/\\&/g')"
扩展正则表达式 (ERE)
- POSIX:扩展正则表达式
- 命令:
grep -E
,sed -E
(旧 GNU 版本:sed -r
) - 特殊字符:
.[\(
- 在某些情况下特别:
*^$+?{|
- 转义字符串:
"$(printf '%s' "$string" | sed 's/[.[\(*^$+?{|]/\\&/g')"
答案2
这取决于应用程序。在你的例子中,[
必须被引用作为参数,grep
但不是echo
。
对于外壳(来自POSIX 规范):
引用用于删除某些字符或单词对 shell 的特殊含义。引用可用于保留下一段中特殊字符的字面含义,防止保留字被识别为保留字,并防止此处文档处理中的参数扩展和命令替换(请参阅此处文档)。
如果应用程序要代表自己,则应引用以下字符:
| & ; < > ( ) $ ` \ " ' <space> <tab> <newline>
在某些情况下可能需要引用以下内容。也就是说,这些字符可能是特殊的,具体取决于 IEEE Std 1003.1-2001 本卷中其他地方描述的条件:
* ? [ # ˜ = %
各种引用机制包括转义字符、单引号和双引号。这里的文档代表了另一种引用形式;请参阅此处文档。
特定程序(使用正则表达式、perl、awk)可能对转义有额外的要求。
答案3
每个应用程序都有自己的一组“特殊”字符。您遇到的问题与grep
外壳无关。对于需要在 中引用哪些字符grep
,请阅读联机帮助页的“正则表达式”部分。
对于 shell,应该引用的字符是:
;'"`#$&*?[]<>{}\
和任何空白。
根据 shell 的不同,可能还需要引用其他字符:
!^%
查看 shell 手册页上的“SHELL GRAMMAR”。
答案4
shell 可能会在命令执行之前转换命令行。 shell 和 都grep
可以使用引号来删除某些字符的特殊含义。尽管如此,grep
贝壳还是有不同的特殊字符。此外,在执行命令之前,shell 会删除并非由现有扩展产生的未转义特殊字符。
echo '[]' | grep '[]'
shell 将参数传输[]
给grep
,并被 解析为格式错误的括号表达式grep
。
echo '[]' | grep \[]
上面,我们可以看到一个类似的案例。反斜杠被删除并[]
作为参数传输到grep
。grep
识别格式错误的括号表达式。
echo '[]' | grep '\[]'
最后,在这种情况下,引号被 shell 删除并\[]
作为参数传输到grep
but,在这种特定情况下,\[
被解释grep
为文字括号。需要使用引号来防止 shell 将反斜杠解释为特殊字符。
^POSIX规范。