2013-07-16 88 views
4

也许这是因为我完全炸的权利,但是这个代码:C#.NET正则表达式工作不正常

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

我想你必须使用'Groups'属性来访问子组。 –

+0

迈克是对的。你混淆与团体的比赛。 – Sven

+0

作为一个观点,Regex有没有组1.1“? 'vdi1.0.exe'中不会发生这种情况。你是不是指'1.0'? – voithos

回答

8

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

试着这么做:

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; 

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

此外,如果您始终只解析单个文件名,则根本没有理由循环使用MatchCollection。您可以更改:

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

要:

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

为了获得一个Match对象,通过名称或索引来访问每个Group

+0

感谢迈克 - 我甚至不知道命名组。我现在就是这样做的。 – Bodacious