C#正则表达式替换和*

C#正则表达式替换和*,c#,perl,C#,Perl,我是一名perl程序员,会做一些C#。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" 文档确实说“在替换模式中,*字符不被识别为元字符” 为什么

我是一名perl程序员,会做一些C#。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);

马特·费罗斯对如何解决这个问题有正确的答案。我相信我可以试着解释为什么它会那样断裂

考虑这一点:

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

它将返回:

!!!||A!!!||A!!!||A!!!||
在本例中,Z*将匹配一系列零长度字符串,每个字符串位于一个字符之前或之后。
$&
放入匹配的字符串,在本例中,我们可以看到该字符串为空

我相信类似的事情也会发生

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

!!!|AAA|!!!||
A*匹配从开头开始,匹配“AAA”。然后它与“”匹配,然后停止

我不确定在这种情况下这是否是理想的行为,但我怀疑这是a*匹配零长度字符串的方式的一个必要的副作用


当然,当您将模式更改为
^A*$
时,锚定意味着只有一个可能的匹配,并且与本例中预期的匹配更为相似。

@rich.okelly,这真的很重要吗?有趣,仅供参考:^\w*$很好。@ingenu给出了答案-应该在Perl和C#中工作。有趣的。。。看起来像一个bug,好像它将EOL视为一个单独的可匹配项。(替换模式是“B”,所以这是一条红鲱鱼。)这一定是个bug:这个
Regex.Replace(“,,@”\w*,“B”)
变成
B.B,BB
这是一个非常好的问题!归结起来,问题是:为什么
Regex.Matches(“A“,@“\w*”).Count
等于
2
而不是
1
?尽管如此,对我来说,为什么仍然是一个悬而未决的问题。毕竟,
“A”
也是65个空字符串,后面跟着
A
,后面跟着324个空字符串,那么为什么
2
匹配而不是
390
?!你能解释为什么这是出于兴趣吗?确实如此,但我感兴趣的是,为什么原始示例中观察到的行为,以及为什么您需要这样做……似乎
^\w*
已经足够了,但我非常想知道为什么。@Ingenu:在您刚问完这个问题后,我想我已经回答了。:)我也想知道为什么@迪斯特这里的一些答案很接近于解释原因。我自己在玩的时候也得出了同样的结论。如果您使用
+
(1或更多)而不是
*
(0或更多),这也解决了问题。是的,当然问题是为什么首先使用
*
而不是
+
。例如,在字符串为空的情况下,可能有一个很好的理由需要匹配。此外,如果您想编辑答案以反映此信息,欢迎您。我确实觉得有点像是在嘲笑你的答案,因为如果没有你的初步观察,我是不可能到达这里的嘿-我已经在我的答案中加入了
+
vs
*
部分,但是你的答案要完整得多,所以我会留给你;)很快将不得不启动一个新线程-但是为什么
string s=Regex.Replace(“.a.”,@“\w*”,“B”)
give
B.BB.B
-它应该是
B.BBB.B
或者
B.B.B
不是吗?