sed - 为什么“[.]”与行的开头和结尾匹配?[复制]

sed - why '[.]' matches with the beginning and end of a line? [duplicate]

提问人:mon 提问时间:10/8/2023 更新时间:10/8/2023 访问量:72

问:

为什么一行的开头和结尾与 匹配以及如何避免它?[.]*

似乎 patten 与单词边界匹配,但不确定它是否符合设计以及它实现的规范。

$ echo " a " | sed -n 's/[.]*/X/pg'
X XaX X

$ echo " a " | sed -n 's/[\b]*/X/pg'
X XaX X
正则表达式 SED

评论

1赞 InSync 10/8/2023
*表示“0 或更多”。它总是匹配的。
0赞 InSync 10/8/2023
可能的重复项:为什么在 javascript 中使用正则表达式模式匹配字符串时在输出数组中添加空字符串?为什么 String.match( /\d*/ ) 返回空字符串?
0赞 knittl 10/8/2023
内容和标题不匹配

答:

2赞 jhnc 10/8/2023 #1

请注意,括号内没有特殊含义。它只是一个字符列表。\b

[.]*并匹配号中的零个或多个字符。[\b]*

因此,它们匹配一个或多个字符的任何运行,其中紧接在字符运行之前和之后的空字符串只是该运行的一部分。

它们还匹配任何不紧接在字符运行之前或之后的空字符串。


用更明显的东西替换空格,你的输入是:sas

字符串中没有字符,也没有出现任何字符。因此,没有长度为一或更长的运行。使用此输入,两个 和 都等同于“匹配空字符串”。.\b[.]*[\b]*

  • 行首和第一个匹配项之间的空字符串s
  • first 和 matches 之间的空字符串sa
  • 和秒之间的空字符串匹配as
  • 第二行和行尾之间的空字符串匹配s

这 4 个匹配项解释了添加到示例输出中的 s。X


使用表示单词边界不是标准的,尽管某些版本接受它(或相关的 和 )。\bsed\<\>

不使用此扩展更安全,当然也不使用 .*

即使是支持它的版本也会产生不直观和不一致的结果。sed

例如,在 GNU sed 4.8 中:

$ echo ,aa, | sed 's/\b/x/g'
,xaax,
$ echo ,aa, | sed 's/\b*/x/g'
,aa,
$ echo ,aa, | sed 's/\b\{1,\}/x/g'
sed: -e expression #1, char 14: Invalid preceding regular expression
$ echo ,aa, | sed 's/\(\b\)\{1,\}/x/g'
,xaax,

使用 busybox sed 1.30.1:

$ echo ,aa, | busybox sed 's/\b/x/g'
,xaxa,
$ echo ,aa, | busybox sed 's/\b*/x/g'
,aa,
$ echo ,aa, | busybox sed 's/\b\{1,\}/x/g'
sed: bad regex '\b\{1,\}': Invalid preceding regular expression
$ echo ,aa, | busybox sed 's/\(\b\)\{1,\}/x/g'
,xaxa,

甚至像Perl这样的其他程序也需要注意:

$ echo ,aa, | perl -ple 's/\b/x/g'
,xaax,
$ echo ,aa, | perl -ple 's/\b*/x/g'
x,xaxax,x
$ echo ,aa, | perl -ple 's/\b{1,}/x/g'
'1,' is an unknown bound type in regex; marked by <-- HERE in m/\b{1, <-- HERE }/ at -e line 1.
$ echo ,aa, | perl -ple 's/(\b){1,}/x/g'
,xaax,
$ echo ,aa, | perl -ple 's/\b+/x/g'
,xaax,

评论

0赞 jhnc 10/8/2023
BusyBox 不正确的结果似乎是由于一个长期存在的错误:bugs.busybox.net/show_bug.cgi?id=5090