没有行开头和结尾终结符的Regex.Replace有一些非常奇怪的效果....这里发生了什么?

Mat*_*ows 10 c# regex replace

在回答这个问题时,C#Regex Replace和*提出了问题存在的原因.在播放时我制作了以下代码:

    string s = Regex.Replace(".A.", "\w*", "B");
    Console.Write(s);
Run Code Online (Sandbox Code Playgroud)

这有输出: B.BB.B

我得到0长度字符串在.字符之前和之后匹配,但为什么A被2个B替换.

我可以理解B.BBB.B为替换任意一侧的零长度字符串AB.B.B 但实际结果让我感到困惑 - 任何帮助表示赞赏.

或者正如AakashM所说:

为什么Regex.Matches("A", "\w*").Count等于2,不是13

Ale*_*aga 12

\ w之后有一颗星

它意味着" 或多",这意味着:

  • 第一个符号是一个点,它不是\ w所以这里有零\ w,用B代替
  • 接下来我们有一个点本身,这是不可替换的
  • A被B取代
  • 在下一个点之前为零\ w,由B替换
  • 点,不可替换
  • 行结束,零\ w因此再次替换为B.

表达\w{0,}将具有相同的效果.

如果你想避免它,请使用'plus',意思是'至少一个': \w+


ste*_*ema 6

这是相同的行为

Regex.Replace("", "\w*", "B")结果B
Regex.Replace("A", "\w*", "B")得到BB

在Regexr上看到它

对于字符串".A." \w*匹配在第一个点之前的空字符串,然后在"A","A"之后的空字符串和最后一个点之后的空字符串.

说明

你可以想到吃掉人物的模式,\w*吃掉了"A",下一个字符是一个点,所以这个匹配就完成了,取而代之.但是模式继续匹配的起始位置仍然在A和点之间.点不能匹配,因此它匹配点之前的空字符串,但是此位置完成,下一个开始位置在点之后.


shi*_*t66 4

因为 \w* 是一个贪婪的正则表达式,它试图找到最大的序列。因此它"nothing"在点之前匹配,然后"nothing"A在两个点之间匹配,然后"nothing"在第二个点之前匹配,最后"nothing"在第二个点之后匹配。