前言
也许你想转换这个:
aaaa
到:
1aaa1
所以让我们提出这样的建议:
echo aaaa | sed --regexp-extended 's/(.*)a/1\11/'
→
1aaa1
问题
是1\11
100% 有效且明确的sed
模式吗?我是否遵守了sed
此类替换的所有良好实践?
我的意思是1\11
或许可能是这两者:
- 替换为 char
1
,然后是 1° 匹配组,然后是另一个 char1
(→ 当前行为) - 替换为字符
1
,然后11° 匹配组(→ 导致异常)
目前看来我的 sed 版本有第一种解释。无论如何,我不知道这是否有记录,或者是否可以在sed
.
感谢您的任何澄清。同时我不会在此基础上建造一座城堡。
目前我正在使用 GNU sed 4.7。
答案1
正如用户 @QuartzCristal 所说,在 GNU 的sed
手册页中有这样一条注释:
s/正则表达式/替换/
尝试将正则表达式与模式空间进行匹配。如果成功,则替换与替换匹配的部分。替换可能包含特殊字符 & 来引用模式空间中匹配的部分,以及特殊转义符 \1 到 \9 来引用正则表达式中相应的匹配子表达式。
1
来自通用编程语言(如 Perl),从到没有这种限制9
(因为例如您可以编写1{$19}1
),我没有意识到sed
.所以,我知道目前语法是 100% 正确的,不能以其他方式解释。
这个答案对 GNU sed 有效。不确定它是 POSIX 定义。
答案2
有一个POSIX 中的描述内容如下:
反向引用表达式 '\n' 应与 '\n' 之前的“(”和“)”之间的子表达式匹配的字符串相同(可能为空)。字符“n”应为从 1 到 9 的数字,指定第 n 个子表达式(从模式开头的第 n 个“(”开始并以相应的成对“)”结束的子表达式)。
这将避免任何\10
或\11
.
这是 BRE 的语法,但我们不需要担心 POSIX 中的 ERE,因为它们不允许反向引用。
GNU sed 手册也有同样的规定。我不相信有任何 sed 允许比\1...\9
反向引用更多的功能。
此外,替换的右侧s///
可能包含捕获括号的引用。那些是Posix 中没有明确划分:
字符“\n”(其中 n 是数字)应替换为与相应反向引用表达式匹配的文本。
但它似乎使用与反向引用相同的规则。
GNU sed 确实明确指出:
反向引用用反斜杠和单个数字(例如“\1”)指定。
Perl 是一种允许更多反向引用的语言。但在该语言中,会编写超过一位数字的反向引用${23}
。我想这样的规定或类似的规定通常是为了避免混淆。