正则表达式是一种特殊的语言。您必须准确理解(.*)将匹配哪些内容。您还需要了解贪婪性。
*将贪婪地匹配0个或多个字符。因此,在字符串"XYZ"中,它将使用第一个匹配项匹配整个字符串并将其放置在$1位置,从而为您提供以下结果:
A XYZ B
然后它将继续尝试匹配,并在字符串末尾匹配null,将$1设置为null,从而为您提供以下结果:
A B
导致您看到的字符串如下:
A XYZ BA B
如果您想限制贪婪度并逐个匹配每个字符,则可以使用以下表达式:
(.*?)
这将分别匹配每个字符X、Y和Z,以及末尾的null,并得到以下结果:
A BXA BYA BZA B
如果您不希望您的正则表达式超出给定字符串的范围,则请使用^和$标识符限制您的正则表达式。
为了让你更好地理解正在发生的事情,请考虑这个测试以及相应的匹配组。
[TestMethod()]
public void TestMethod3()
{
var myText = "XYZ";
var regex = new Regex("(.*)");
var m = regex.Match(myText);
var matchCount = 0;
while (m.Success)
{
Console.WriteLine("Match" + (++matchCount));
for (int i = 1; i <= 2; i++)
{
Group g = m.Groups[i];
Console.WriteLine("Group" + i + "='" + g + "'");
CaptureCollection cc = g.Captures;
for (int j = 0; j < cc.Count; j++)
{
Capture c = cc[j];
Console.WriteLine("Capture" + j + "='" + c + "', Position=" + c.Index);
}
}
m = m.NextMatch();
}
输出:
Match1
Group1='XYZ'
Capture0='XYZ', Position=0
Group2=''
Match2
Group1=''
Capture0='', Position=3
Group2=''
请注意,有两个匹配的组。第一个是整个XYZ组,第二个是一个空组。尽管如此,仍然有两个匹配的组。因此,在第一种情况下,$1被替换为XYZ,在第二种情况下被替换为
null
。
另外,请注意,前斜杠
/
只是在.NET正则表达式引擎中考虑的另一个字符,并没有特殊含义。JavaScript解析器处理
/
不同,因为它存在于HTML解析器的框架中,其中
</
是一个特殊考虑因素。
最后,要得到您真正需要的内容,请考虑以下测试:
[TestMethod]
public void TestMethod1()
{
var r = new Regex(@"^(.*)$");
var c = "XYZ";
var uc = r.Replace(c, "A $1 B");
Assert.AreEqual("A XYZ B", uc);
}
Replace
将替换它们两个。第一个是 "XYZ",第二个是空字符串。我不确定的是为什么它首先有两个匹配项。你可以使用^(.*)$
来强制它考虑字符串的开头和结尾来解决这个问题。 - Matt Burland