\1 未在 RE 中定义?

\1 未在 RE 中定义?

我的代码是这样的:

cat file.ign | sed 's/^([^A-Za-z0-9]+ )/<ignore>\1<\/ignore>/g'

但我收到一条错误消息:

sed: 1: "s/^([^A-Za-z0-9]+ )/<ig ...": \1 not defined in the RE

答案1

括号是基本正则表达式 (BRE) 语法中的文字 - 要使它们表示捕获组,必须对它们进行转义,如下\(所示\)

此外,正如 @BenjaminW 的评论中所指出的,+在 BRE 中也是字面意思。 GNU sed 支持\+作为 BRE 中的量词:

sed 's/^\([^A-Za-z0-9]\+ \)/<ignore>\1<\/ignore>/g'

(但其他实现可能不会)。或者,根据需要使用-E或命令行开关打开扩展正则表达式 (ERE) 模式(检查您的版本的文档):-r

sed -E 's/^([^A-Za-z0-9]+ )/<ignore>\1<\/ignore>/g'

或使用符合 POSIX 标准的量词\{1,\}

sed 's/^\([^A-Za-z0-9]\{1,\} \)/<ignore>\1<\/ignore>/g'

ASIDE g(全局替换)修饰符在这里不会有任何效果,因为^将表达式锚定到模式的开头(每行只能出现一次)

答案2

使用GNU sed,您可以调用 as ,sed -E或者您可以转义括号以使反向引用起作用,但如果您不使用 GNU sed,则不能依赖反向引用;POSIX sed不(然而) 支持扩展正则表达式 (ERE) 的-Eor-r参数,也不支持 GNU 的基本正则表达式 (BRE) 反斜杠表示法。 (这里是有关 POSIX ERE 和 BRE 的更多信息,尽管它没有深入讨论 GNU 的 BRE 实现,允许转义到 ERE 功能。)

幸运的是,(在本例中)您不需要 ERE。这应该适合你:

sed 's/^[^A-Za-z0-9][^A-Za-z0-9]* /<ignore>&<\/ignore>/' file.ign

BRE 不支持+量词,因此我需要将非单词字符集加倍,以便通过要求“一个”然后“零个或多个”来将其变为“一个或多个”。与号 ( &) 表示整个匹配。在这种情况下,不需要将所有内容都括起来。 (行首锚点^是零宽度,在这里并不重要。)

我删除了,cat因为它是不必要的。我还删除了您的/g修饰符,因为^锚点意味着每行只能匹配一次,因此您永远不会获得第二次匹配,因此全局替换不会执行任何操作。

相关内容