我的代码是这样的:
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) 的-E
or-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
修饰符,因为^
锚点意味着每行只能匹配一次,因此您永远不会获得第二次匹配,因此全局替换不会执行任何操作。