我已经检查^*并匹配以and^&开头的行,因为它们是特殊字符,所以我没有。但不起作用。这是“标准”行为吗?这背后有什么理由吗?*&^[
sed使用的版本是“GNU sed 4.4”。
char 不是特殊的&正则表达式字符,它不需要以正则表达式模式转义。请注意,&可以将其解析为替换模式中的特殊构造,其中 is 指的是整个匹配。
在 GNU 中,当*它位于开头时并不特殊sed(是与字符串开头的^*a 匹配的模式):*
POSIX 1003.1-2001 表示,
*当它出现在正则表达式或子表达式的开头时,它代表自己,但许多非 GNU 实现不支持这一点,而可移植脚本应该\*在这些上下文中使用。
开始一个括号表达式,[并且必须有一个配对]才能关闭表达式,因此这是一个错误。
从POSIX.1-2017开始:
阅读有关 BRE 的 POSIX 部分,我们读到:
BRE 特殊字符在某些上下文中具有特殊属性。在这些上下文之外,或者当前面有 <backslash> 时,这样的字符是匹配特殊字符本身的 BRE。BRE 特殊字符及其具有特殊含义的上下文如下:
.[\: <period>、<left-square-bracket> 和 <backslash> 应该是特殊的,除非在括号表达式中使用(参见RE 括号表达式)。包含未转义且不属于括号表达式的“[”的表达式会产生未定义的结果。*: <asterisk> 应该是特殊的,除非使用:
- 在括号表达式中
- 作为整个 BRE 的第一个字符(在初始的 '^' 之后,如果有的话)
- 作为子表达式的第一个字符(在初始的 '^' 之后,如果有的话);请参阅匹配多个字符的 BRE
^: <circumflex> 在用作锚时应该是特殊的(参见BRE 表达式锚定)。<circumflex> 应表示不匹配的列表表达式,当它首先出现在列表中时,紧跟在 <left-square-bracket> 之后(参见RE 括号表达式)。$: <dollar-sign> 在用作锚点时应该是特殊的。来源:基本正则表达式,特殊字符
因此,要使用上述内容回答 OPs 问题:
&不是特殊字符,因此^&可以正常工作[如果它不用作括号表达式,则应始终对其进行转义。*^当后者是锚点时,在首字母之后并不特殊。因此,OP 观察到的所有陈述都是有效的。
然而,在RE Bracket Expression中仍有一段有趣的段落:
括号表达式要么是匹配的列表表达式,要么是不匹配的列表表达式。它由一个或多个表达式组成:普通字符、整理元素、整理符号、等价类、字符类或范围表达式。如果 <right-square-bracket> ( )在列表中首先出现(在初始 <circumflex>( ) 之后,如果有的话),则< right-square-bracket> (
]) 将失去其特殊含义并在括号表达式中表示自己。否则,它将终止括号表达式,除非它出现在整理符号中(例如)或者是整理符号、等价类或字符类的结尾 <right-square-bracket>。特殊字符, , , 和^[.].].*[\\(分别为 <period>、<asterisk>、<left-square-bracket> 和 <backslash>)在括号表达式中将失去其特殊含义。
这意味着]不能在括号表达式中转义。这表示:
以下工作:
$ echo '[]' | sed 's/[^]x]/a/'
a]
$ echo '[]' | sed 's/[^x[.].]]/a/'
a]
但这不能按预期工作:
$ echo '[]' | sed 's/[^x\]]/a/'
[]
所以在括号表达式中,不要逃避它,而是整理它!