Regex 为什么替换运算符与powershell中的空字符串匹配
在Powershell(5.1或7)中,我运行: 正如您所看到的,在第一次运行中,我得到了Regex 为什么替换运算符与powershell中的空字符串匹配,regex,powershell,replace,Regex,Powershell,Replace,在Powershell(5.1或7)中,我运行: 正如您所看到的,在第一次运行中,我得到了xx,但希望得到一个x。 在bash中尝试了sed(我想是来自gitdir/usr/bin;msys的可执行文件),得到了我所期望的结果 2021-05-01 01:34:27 /r : $ echo "abcdef" | sed -E s/.*/x/g x 2021-05-01 01:35:03 /r : $ echo "abcdef" | sed -E s/.+
xx
,但希望得到一个x
。
在bash中尝试了sed(我想是来自gitdir/usr/bin;msys的可执行文件),得到了我所期望的结果
2021-05-01 01:34:27 /r :
$ echo "abcdef" | sed -E s/.*/x/g
x
2021-05-01 01:35:03 /r :
$ echo "abcdef" | sed -E s/.+/x/g
x
2021-05-01 01:35:08 /r :
$ echo "abcdef" | sed -E s/^.*/x/g
x
2021-05-01 01:35:17 /r :
$ echo "abcdef" | sed -E s/^.+/x/g
x
2021-05-01 01:35:20 /r :
$ echo "abcdef" | sed -E s/^/x/g
xabcdef
2021-05-01 01:35:25 /r :
$
我已经尝试了文档,但不知道如何理解正在发生的事情。让我们来看看
在任何版本的PowerShell中,找出正则表达式模式所匹配内容的最简单方法是使用regex.Matches()
:
啊哈!它匹配子字符串abcdef
,然后匹配f
和字符串末尾之间的空字符串
在PowerShell 7中,我们还可以使用带有替换运算符的脚本块来确认:
PS ~> "abcdef" -replace '.*',{"['$($_.Value)' (length $($_.Length)) starting at $($_.Index)]"}
['abcdef' (length 6) starting at 0]['' (length 0) starting at 6]
恐怕我现在不明白为什么正则表达式引擎实现者认为这种行为比sed的行为更可取,但至少我们知道现在发生了什么。选择显示2个匹配项的字符串:
# select-string highlights matches in ps 7, but you can't see the 2nd match anyway
'abcdef' | select-string .* -AllMatches | % matches # 2 matches
看起来像是.Net的东西,即使在Powershell 7中也是如此。也给出了2个匹配项,所以可能是sed错了(“posix?”.net应该遵循该标准吗?),因为/g表示全局或所有匹配项
[regex]::Replace('abcdef','.*','x')
xx
只替换一次():
在osx中,其工作原理与sed相同。由于某些原因,它只能在bash中工作。哦,您必须在powershell中反斜杠所需的双引号
echo 'abcdef' | awk '{ gsub(/.*/,\"x\"); print }'
x
似乎这是一种正则表达式行为,而不是特定的powershell。返回2个匹配项。不过我无法解释。可能是因为第一个匹配是零匹配,其余的是一个或多个匹配。(在正则表达式中,asteriks表示零个或多个匹配)?Theo不,这是另一种方式-第一个匹配是
abcdef
,第二个是f
和string@MathiasR.Jessen但愿上帝知道!。我通过锚定到字符串“abcdef”-replace.*$,“x”
-->xx
,同时锚定到字符串的开头“abcdef”-replace'^.*',“x”
返回单个x
这是RegexBuddy对它的理解-在选择.NET
时会显示相同的警告,因此看起来像是一般的.NET
thingNice演示;至于原因:长时间的讨论,但对我来说仍然没有充分的意义。@mklement0有一条关于sed和awk的“posix最左最长匹配”的评论。Regex101.com显示了2个匹配项。@mklement0有趣的观察结果。之前我并没有认真考虑过,我最初的直觉实际上是“sed很奇怪,很友好,.NET的行为就像我所期望的那样”,正如你在中途指出的(即“位置N是macthing的一个完全有效的偏移量”)是的,sed
和awk
(BSD/macOS和GNU/Linux实现在全球范围内只匹配一次*
;mawk的情况也是如此。Python2.x和Python到v3.6也只匹配一次,但从我所知的情况来看,大多数引擎匹配两次。一个例外是不幸需要\
-逃避“
chars.PowerShell Core 7.2.0-preview.5引入了实验性功能PSNativeCommandArgumentPassing
,这使得它不再是必需的;它在Unix平台上运行良好,但在Windows上缺少重要的调整;此外,目前还存在一些错误-请参阅。很好,感谢带有解释的regex101链接。
[regex]::Replace('abcdef','.*','x')
xx
$pattern = [regex]'.*'
$pattern.replace('abcdef','x',1)
x
echo 'abcdef' | awk '{ gsub(/.*/,\"x\"); print }'
x