2013-07-16 41 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