1

我已经检查^*并匹配以and^&开头的行,因为它们是特殊字符,所以我没有。但不起作用。这是“标准”行为吗?这背后有什么理由吗?*&^[

sed使用的版本是“GNU sed 4.4”。

4

2 回答 2

2

请参阅sed“3.3 正则表达式语法概述”文档

char 不是特殊的&正则表达式字符,它不需要以正则表达式模式转义。请注意,&可以将其解析为替换模式中的特殊构造,其中 is 指的是整个匹配。

在 GNU 中,当*它位于开头时并不特殊sed(是与字符串开头的^*a 匹配的模式):*

POSIX 1003.1-2001 表示,*当它出现在正则表达式或子表达式的开头时,它代表自己,但许多非 GNU 实现不支持这一点,而可移植脚本应该\*在这些上下文中使用。

开始一个括号表达式,[并且必须有一个配对]才能关闭表达式,因此这是一个错误。

于 2018-08-21T08:20:37.483 回答
2

POSIX.1-2017开始:

sed 实用程序应支持 XBD基本正则表达式中描述的 BRE ,... [ sed ]

阅读有关 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>)在括号表达式中将失去其特殊含义。

来源:基本正则表达式、RE 括号表达式

这意味着]不能在括号表达式中转义。这表示:

以下工作:

$ echo '[]' | sed 's/[^]x]/a/'
a]
$ echo '[]' | sed 's/[^x[.].]]/a/'
a]

但这不能按预期工作:

$ echo '[]' | sed 's/[^x\]]/a/'
[]

所以在括号表达式中,不要逃避它,而是整理它!

于 2018-08-21T18:00:03.877 回答