使用 GNU sed(-r为了清楚起见,带有标志),输入字符串上的以下两个替换ab给出了相同的结果:
s/(.)(.)|(.)(.)$/\2\1\3\4/
和
s/(.)(.)$|(.)(.)/\1\2\4\3/
都给ba。看起来替代品(.)(.)(没有的替代品$)在两种替换中都成功了,无论其位置是第一个替代品还是第二个替代品。为什么会这样?这种替代方案的决胜局是什么?
正则表达式的 POSIX 规范指定1当备选方案从不同位置开始时(在这种情况下优先选择较早的位置),以及当它们从相同位置开始但具有不同长度(优先选择较长的位置)时,决胜局,但是当两个备选方案从相同位置开始并具有相同长度时,它似乎没有指定捕获组的行为,因此将其留给具体实现。
匹配序列的搜索从字符串的开头开始,并在找到与表达式匹配的第一个序列时停止,其中“first”定义为“在字符串中最早开始”。如果模式允许可变数量的匹配字符,因此从该点开始有多个这样的序列,则匹配最长的这样的序列。[...] – The Open Group Base Specifications 第 7 期,2018 年版
这是该现象的一个运行示例。
echo ab|sed -r 's/(.)(.)|(.)(.)$/\2\1\3\4/'
echo ab|sed -r 's/(.)(.)$|(.)(.)/\1\2\4\3/'