提问人:mon 提问时间:10/7/2023 更新时间:10/9/2023 访问量:72
sed - 解释奇怪行为以替换重复的 ]\.*
sed - explanation of the strange behavior to replace the repetition of ]\.*
问:
请帮助了解以下意外行为以及如何解决。
要替换 or 的重复,我可以用 .a
b
[ab]*
$ echo "abab" | sed -n 's/[ab]*/X/gp'
X
但是,不能按预期工作,产生如下结果,导致额外的替换。[]\.*]*
a X b
$ echo "a \.*] b " | sed -n 's/[]\.*]*/X/pg'
XaX X XbX X
如果在正则表达式模式中不重复表达式,则一一替换,则有效。*
$ echo "a \.*] b " | sed -n 's/[]\.*]/X/pg'
a XXXX b
因此,我怀疑重复表达导致了问题,但不确定出了什么问题。*
环境:
Mac OS 13.0.1 (22A400)
$ sed --version
sed (GNU sed) 4.9
答:
我发现有趣的是,字符类允许在第一个位置使用方括号,而没有转义。这是我不知道的好速记。
echo '1[]2[]3[]4' | sed 's/[]]/x/g'
1[x2[x3[x4
我以为需要转义,但第一个位置似乎也使反斜杠成为字面上的反斜杠:]
\]
echo '1[]2[]3[]4' | sed 's/[\]]*/x/g'
1[]2[]3[]4
...令人惊讶的是,这什么也没取代,因为它正在寻找字面上的反斜杠来锚定比赛。
因此,了解这里发生的事情会有所帮助:
$ echo '1[\]2[\]3[\]4' | sed 's/[\]/x/g'
1[x]2[x]3[x]4
$ echo '1[\]2[\]3[\]4' | sed 's/[\]]/x/g'
1[x2[x3[x4
...第二个是令人困惑的。为什么有一个 x?哦,因为它是作为单匹配匹配的。\]
因此,我必须得出结论,除了字符类中的第一个位置之外,必须在任何地方转义右方括号。字面上的反斜杠有点相同(但在最后一个位置也可以容忍)。事实证明,IEEE标准支持这里。部分。的含义必须在别处讨论。]
\
]
\
正在发生的另一件事是,这意味着“零或多次出现”,因此您还会看到替换与所有字符边界匹配:*
echo '1[]2[]3[]4' | sed 's/[]]*/x/g'
x1x[x2x[x3x[x4x
...对我来说,这并不奇怪。正如评论所说,在 BRE 中,您可以使用而不是表示“一个或多个”。在 ERE 中,这变成了一个简单的 .\+
*
+
最后,“或更多”可能会令人困惑:
$ echo abab | sed 's/[ab]*/X/g;'
X
$ echo abab | sed 's/[ab]/X/g;'
XXXX
$ echo abcab | sed 's/[ab]/X/g;'
XXcXX
$ echo abcab | sed 's/[ab]*/X/g;'
XcX
...啊哈,是的。 将 A 和 B 的不间断字符串作为单个匹配项进行匹配。[ab]*
评论
\+
\{1,\}
?
\{0,1\}
您从 .
这看起来不错,因为您的输入只有匹配的字符。另一个输入字符串也有同样的问题。echo "abab" | sed -n 's/[ab]*/X/gp'
echo "string with abab inside" | sed -n 's/[ab]*/X/gp'
XsXtXrXiXnXgX XwXiXtXhX X XiXnXsXiXdXeX
这是因为还匹配长度为 0 的字符串。
您可以通过替换为 来修复它。*
*
\+
echo "string with abab inside" | sed -n 's/[ab]\+/X/gp'
string with X inside
# Or avoid the backslash with the '-r' option
echo "string with abab inside" | sed -rn 's/[ab]+/X/gp'
string with X inside
其他字符集的大小写也以相同的方式工作。
echo "a \.*] b " | sed -n 's/[]\.*]\+/X/pg'
a X b
使用 BRE,可以这样写
echo "a \.*] b " | sed -rn 's/[]\.*]{1,}/X/pg'
a X b
评论
[ab]
表示 'a' 或 'b',而不是 'ab'(尝试 aabb 作为输入)。对于 ab,请尝试(ab)
*
\+
echo "x bb x" | sed -n 's/[ab]*/X/gp'
演示了第一个示例如何遇到完全相同的问题。输出:XxX X XxX
正则表达式
标记信息页面有一节是关于方括号含义的,如果您确实希望它们之间的文本逐字匹配。投票关闭为错别字(尽管我敢肯定,关于它的含义和它如何匹配根本没有文本,也有重复)。*