2013-11-14 51 views
2

爲什麼正則表達式工作不正常?正則表達式「,\ s(。*?),\」

string findarg2 = ",\\s(.*?),\\s"; 

foreach (Match getarg2 in Regex.Matches(tmptwopart, findarg2)) 
if (getarg2.Success) 
{ 
    for (int m = 1; m < getarg2.Groups.Count; m++) 
    { 
     int n; 
     bool needpointer = false; 
     for (n = getarg2.Groups[m].Value.Length - 1; n > -1; n--) 
     { 
      if (getarg2.Groups[m].Value[n] == ' ') 
       break; 
      else if (getarg2.Groups[m].Value[n] == '*') 
      { 
       needpointer = true; 
       break; 
      } 
     } 
     n++; 

     string part1 = getarg2.Groups[m].Value.Remove(n); 
     string part2 = getarg2.Groups[m].Value.Remove(0, n); 
     Console.WriteLine(getarg2.Groups[m] + " =->" +part1+ " AND " + part2); 
     Console.ReadKey(); 
     if (needpointer) 
     { 
      createarglist.Append("<< *(" + part1 + ")" + part2); 
     } 
     else 
     { 
      createarglist.Append("<< " + part2); 
     } 
     createarglistclear.Append(part2+","); 
    } } 

例如,輸入字符串:

(DWORD code, bool check, float *x1, float *y1, float *x2, float *y2) 

輸出:

<< check<< *(float *)y1 

預計:

<< check<< *(float *)x1<< *(float *)y1<< *(float *)x2 
+2

這是什麼問題? – Matthew

+3

您的預期產出是多少? –

+0

需要<<檢查<< *(float *)x1 << *(float *)y1 << *(float *)x2 –

回答

3

表達式不起作用的原因是它「消耗」了逗號:與check相匹配的部分也會在逗號後吃掉逗號,從而阻止float *x1被匹配;與float *y1匹配的表達式也一樣。

更改表達式以使用lookahead和lookbeheads應該有效。然而,這可能還不夠,因爲第一場比賽前面不會有逗號,最後一場比賽之後不會有逗號。

更好的表達在這種情況下使用應該是這樣的:

(?<=[(,])\\s*([^,)]*)\\s*(?=[,)]) 

下面是一個完整的代碼示例:

foreach (Match m in Regex.Matches(
    "(DWORD code, bool check, float *x1, float *y1, float *x2, float *y2)" 
, "(?<=[(,])\\s*([^,)]*)\\s*(?=[,)])") 
) { 
    for (var i = 1 ; i != m.Groups.Count ; i++) { 
     Console.WriteLine("'{0}'", m.Groups[i]); 
    } 
} 

這裏是一個demo on ideone製備六組爲預期:

'DWORD code' 
'bool check' 
'float *x1' 
'float *y1' 
'float *x2' 
'float *y2' 
+0

+1 - 關於第一場和最後一場比賽的好處。對於@FakEFake,在這種情況下,可以在斷言中使用'|'運算符來允許更靈活的情況。 (C#允許可變寬度lookbehinds,所以它會工作。) –

4

這是因爲你,你去消費後的逗號。也就是說,您已經匹配了尾隨逗號,因此它不會匹配您嘗試匹配的下一個實體的前導逗號。改爲使用零寬度斷言:

string findarg2 = "(?<=,\\s)(.*?)(?=,\\s)"; 

這分別稱爲「lookbehead」和「lookahead」斷言。

+0

謝謝!有用。 –

0

這可以一次完成:

string input = "(DWORD code, bool check, float *x1, float *y1, float *x2, float *y2)"; 
string pattern = @"(?:\([^,]*,\s*[^\s,]*\s+([^,]+)|\G),\s+(\S+)\s*(\*)?((?>[^*,)]+))(?>(?=,[^,]+,)|.*)"; 
string replacement = "$1<< *($2$3)$4"; 
Regex rgx = new Regex(pattern); 
string result = "<<" + rgx.Replace(input, replacement); 
+0

不,這是絕對錯誤的。 –

+0

@FakEFake:怎麼了? –

+0

@FakEFake:我忘記了模式字符串之前的@。現在就試試。 –

相關問題