4

也许是因为我现在完全炸了,但是这段代码:

static void Main(string[] args)
    {
        Regex regx = new Regex(@"^.*(vdi([0-9]+\.[0-9]+)\.exe).*$");
        MatchCollection results = regx.Matches("vdi1.0.exe");
        Console.WriteLine(results.Count);

        if (results.Count > 0)
        {
            foreach (Match r in results)
            {
                Console.WriteLine(r.ToString());
            }
        }
    }

应该产生输出:

2
vdi1.0.exe
1.0

如果我不疯的话。相反,它只是产生:

1
vdi1.0.exe

我错过了什么?

4

1 回答 1

8

您的正则表达式将只返回一个Match具有 2 个子组的对象。Groups您可以使用对象的集合访问这些组Match

尝试类似:

foreach (Match r in results) // In your case, there will only be 1 match here
{
   foreach(Group group in r.Groups) // Loop through the groups within your match
   {
      Console.WriteLine(group.Value);
   }
}

这允许您匹配单个字符串中的多个文件名,然后遍历这些匹配项,并从父匹配项中获取每个单独的组。这比像某些语言那样返回单个扁平化数组更有意义。另外,我会考虑给你的团体起名字:

Regex regx = new Regex(@"^.*(?<filename>vdi(?<version>[0-9]+\.[0-9]+)\.exe).*$");

然后,您可以按名称引用组:

string file = r.Groups["filename"].Value;
string ver = r.Groups["version"].Value;

这使代码更具可读性,并允许更改组偏移量而不会破坏事物。

此外,如果您总是只解析一个文件名,则根本没有理由循环 a MatchCollection。你可以改变:

MatchCollection results = regx.Matches("vdi1.0.exe");

至:

Match result = regx.Match("vdi1.0.exe");

获取单个Match对象,并按Group名称或索引访问每个对象。

于 2013-07-16T22:03:47.173 回答