regex sed -为什么'[.]'与行的开头和结尾匹配?[副本]

yqhsw0fo  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(107)

此问题已在此处有答案

[sed - explanation of the strange behavior to replace the repetition of ].*](https://stackoverflow.com/questions/77248529/sed-explanation-of-the-strange-behavior-to-replace-the-repetition-of)(2个答案)
Why does String.match( / \d*/ ) return an empty string?(4个答案)
13天前关闭
为什么一行的开头和结尾会被[.]*匹配,如何避免?
看起来模式与单词边界匹配,但不确定它是否符合设计以及它实现的规范。

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

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

vc9ivgsu1#

请注意,括号内的\b没有特殊含义。它只是一个字符列表。
[.]*[\b]*匹配括号中的零个或多个字符。
因此,它们匹配一个或多个字符的任何串,其中紧接在字符串之前和之后的空字符串只是该串的一部分。
它们还匹配任何没有紧接在字符串之前或之后的空字符串。
用更明显的东西代替空间,你的输入是:sas
字符.\b都没有出现在字符串中。所以不存在长度为1或更长的游程。对于这个输入,[.]*[\b]*都相当于“匹配空字符串”。

  • 行首和第一个s之间的空字符串匹配
  • 第一个sa之间的空字符串匹配
  • a和第二个s之间的空字符串匹配
  • 第二个s和行尾之间的空字符串匹配

这4个匹配解释了添加到示例输出中的X s。
使用\b表示单词边界并不标准,尽管一些sed版本接受它(或相关的\<\>)。
不使用此扩展更安全,当然也不使用*
即使是支持它的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,

相关问题