在 vi 中,对于行
aaaj
我运行命令:
.s/a*\|j/x/g
线变成
xj
而不是预期的
xx
这是vi的错误吗? sed、gawk 和 nawk 的行为符合预期,例如:
% echo aaaj | awk '{gsub(/a*|j/,"x");print}'
xx
另外,如果我运行命令而不是上面的命令
.s/j\|a*/x/g
(“j”和“a*”交换),那么该行将按预期变为“xx”。
最佳答案
这里的“问题”是 a*
作为交替中第一个分支的子模式可以匹配空字符串。
当引擎发现 aaa
, a*
替代分支匹配三个 a
s 和 substitute
将它们全部替换为 x
.然后,引擎尝试在 3 a
之后的位置再次匹配。 s + 1(见 source code comments)。
请注意 a*
始终匹配、“获胜”和 j
永远不会匹配。这是因为优先顺序,第一个分支总是在 Vim 正则表达式中获胜。如果更换 aaaj jjj
它将变成 xjx xjxjxj
因为模式将匹配非匹配字符之前的每个位置。
正确的模式
用正则表达式替换时,通常不希望匹配与模式不匹配的字符之间的所有空位置,因此,合乎逻辑的解决方案是使用 +
量词, a\+\|j
图案 .
关于regex - 是否有上下文替换的标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36299669/