C#正则表达式替换和*

我是一个做C#的perl程序员。 面对与零或多个断言有关的Regex.Replace的奇怪问题,*。

假设我想用一个字母替换零个或多个字母。 在perl中,我可以这样做:

my $s = "A"; $s =~ s/\w*/B/; print $s; $s now = "B" 

但是如果我尝试在C#中做同样的事情,就像这样:

 string s = Regex.Replace("A", @"\w*", "B"); s now = "BB" 

文档确实说“*字符在替换模式中不被识别为元字符”

为什么? 如果你想要一些你的正则表达式在一些字符串上留下可能不存在的字符串(如最后的“。*?”),是否有任何解决方法?

(这是一个愚蠢的例子,但你明白了)

用^开始你的模式,用$结束它,你的问题就解决了。

 string s = Regex.Replace("AAAA", @"^\w*$", "B"); Console.Write(s); 

或者 – 您可以使用+运算符而不是*运算符停止匹配0长度字符串:

 string s = Regex.Replace("AAAA", @"\w+", "B"); Console.Write(s); 

Matt Fellows对如何修复它有正确的答案。 我相信我可以尝试解释为什么它会像那样打破……

考虑一下:

Regex.Replace(“AAA”,@“Z *”,“!!! | $&|”)

它将返回:

 !!!||A!!!||A!!!||A!!!|| 

在这种情况下,Z *将匹配一系列零长度字符串,每个字符串位于一个A字符之前或之后。 $&放入匹配的字符串,在这种情况下我们可以看到它是空的。

我相信类似的事情

 Regex.Replace("AAA", @"A*", "!!!|$&|") 

哪个回报

 !!!|AAA|!!!|| 

A *匹配从头开始并匹配“AAA”。 然后匹配“”然后停止。

在这种情况下,我不确定这是否是期望的行为,但我怀疑它是A *匹配零长度字符串的方式的必要副作用。

当然,当您将模式更改为^A*$ ,锚定意味着只有一个可能的匹配,并且更像是在这种情况下的预期。