为什么 space 会导致 sed 中记住的模式输出不同的东西

Why does a space cause the remembered pattern in sed to output different things

我正在尝试通过终端获取此 xml 行中值条目的值,因此我正在使用 sed。

abcs='<param name="abc" value="bob3" no_but_why="4"/>'

echo $abcs | sed -e 's/.*value="\(.*\)" .*//'
echo $abcs | sed -e 's/.*value="\(.*\)".*//'

输出为:

bob3
bob3" no_but_why="4

为什么没有 space 的第二种方式导致的不仅仅是我想要打印的内容?为什么 \1 会受到影响

如您所见,不同之处在于在 " 之后的第二个正则表达式中使用了贪婪模式 .* 而没有 space.

它表现不同的原因是在 no_but_why= 之后也有一个双引号,并且 .* 作为一个贪婪模式一直匹配到 /> 之前的最后一个 "在第二个正则表达式中。

在你的第一个正则表达式中 "\(.*\)" 只匹配 "bob3" 因为在这之后有一个 space 这使得正则表达式引擎阻止 .* 匹配直到输入中的最后一个双引号.

为了避免这种情况你应该使用否定字符class而不是贪婪匹配。

考虑这些 sed 命令示例:

sed -e 's/.*value="\([^"]*\)" .*//' <<< "$abcs"
bob3

sed -e 's/.*value="\([^"]*\)".*//' <<< "$abcs"
bob3

现在您可以看到两个命令都产生相同的输出 bob3 因为 否定字符 class [^"]* 将匹配直到它到达下一个 " 直到输入的最后一个 " 就像 .*.

的情况一样