我知道特殊字符会产生特殊动作:
$ echo 'abc[abc' | grep -o '['
grep: Invalid regular expression
请注意,单引号可以避免 shell 解释或源字符串更改出现问题。
我还知道需要反斜杠来转义这些特殊字符的特殊解释:
$ echo abc[abc | grep -o '\['
[
为了匹配 backslash-specialChar ( \[
) grep 需要更多的反斜杠:
$ echo 'abc\[abc' | grep -o '\\\['
\[
但是像 an 这样的简单字符f
并不特殊,匹配 a\f
应该不需要额外的逃脱:
$ echo 'abc\fabc' | grep -o '\f'
f
但它确实:
$ echo 'abc\fabc' | grep -o '\\f'
\f
A文字字符串,如:
$ echo 'abc\fabc' | grep -F -o '\f'
\f
去证明\f
grep 以某种方式解释了 。
这手动的状态:
'\' 字符后跟某些普通字符时,具有特殊含义:
/s
匹配空格,它是 '[[:space:]]' 的同义词。
暗示certain ordinary characters
还有其他普通人物不在该列表中并且没有特别的地位。
因此,我的理解是 a \f
(仅选择一个字符)应该匹配源字符串\f
.
我缺少什么?
有关的:
1-grep:尾部反斜杠。
答案1
但是像 f 这样的简单字符并不特殊,匹配 \f 不需要额外的转义:
$ echo 'abc\fabc' | grep -o '\f' f
f
并不特殊,但反斜杠在正则表达式中很特殊。常规字符前面的反斜杠的行为在实现反斜杠转义的不同实用程序中有所不同,但如下所示对于 POSIX 正则表达式,定义指出:
对前面带有未转义字符 ( '\' ) 的普通字符的解释是不明确的,但以下情况除外:[
(){}
、1
到9
括号内的表达式中的任意一个 ]
类似地,在扩展正则表达式中:
普通字符是受支持的字符集中的任何字符,除了 ERE 特殊字符中列出的 ERE 特殊字符。前面带有未转义 ( ) 的普通字符的解释
\\
是未定义的,除非在括号表达式的上下文中(请参阅 ERE 括号表达式)。
grep
(或者更确切地说,它使用的正则表达式实现)只是选择解释\f
为与f
.人们可能会认为反斜杠删除了 the 的任何特殊属性f
(即使它没有任何特殊属性),这与反斜杠在 ERE 中的工作方式一致。或者作为任意决定。
这Linux 手册页regex(7)
明确解释:
原子是[除其他外] a
\
后跟任何其他字符(!)(匹配该字符作为普通字符,就好像\
不存在一样(!))
在我的 Mac 上,它grep
代表\f
换页符,就像 C 风格的转义符一样。所以printf '\f' | grep '\f'
匹配,他们都将其解释为换页(printf
被定义为这样做)。
答案2
我缺少什么?
就 grep 字符串而言,因为f
它是正则表达式中的普通字符,'\f'
所以与以下内容相同'f'
:
$ echo 'abc\fabc'
abc\fabc
$ echo 'abc\fabc' | grep -o '\f'
f
$ echo 'abc\fabc' | grep -o 'f'
f
但是像 f 这样的简单字符并不特殊,不需要转义:
$ echo 'abc\fabc' | grep -o '\f'
f
但它确实:
$ echo 'abc\fabc' | grep -o '\\f'
\f
不,事实并非如此。回顾一下我之前的例子:
$ echo 'abc\fabc' | grep -o 'f'
f
的手册页re_format(7)
记录 regexp\f
等同于 regexp f
:
... '\' 后跟任何其他字符(与视为普通字符的字符匹配,就好像 '\' 不存在一样) ...