2011-12-11 90 views
6

我使用此代碼檢查一個字符串中,我加載到內存中獲取行號匹配的模式

foreach (Match m in Regex.Matches(haystack, needle)) 
    richTextBox1.Text += "\nFound @ " + m.Index; 

正則表達式返回匹配發生時的位置,但我想 到一個文本文件中存在知道行號?

回答

5

最好解決方法是調用只有在匹配發生時才獲取行號的方法。 這樣,如果檢查多個文件並且\n的正則表達式可以正常工作,則性能不會受到太大影響。發現這個方法某處計算器:

public int LineFromPos(string S, int Pos) 
    { 
     int Res = 1; 
     for (int i = 0; i <= Pos - 1; i++) 
      if (S[i] == '\n') Res++; 
     return Res; 
    } 
5

你可以先文本分成行和你的正則表達式應用到每一行 - 當然是不一樣,如果needle工作包括一個新行:

var lines = haystack.Split(new[] { Environment.NewLine }, StringSplitOptions.None); 
for(int i=0; i <lines.Length; i++) 
{ 
    foreach (Match m in Regex.Matches(lines[i], needle)) 
     richTextBox1.Text += string.Format("\nFound @ line {0}", i+1) 
} 
+0

我覺得一個更具吸引力的選擇是使用'StringReader'的草垛和使用'的ReadLine()'讀取線,而不是分裂它的方式。 –

+0

true - 我假定'haystack'已經加載到內存中,如果不是,對於更長的文件,絕對會使用'File.ReadLines()' – BrokenGlass

0
foreach (Match m in Regex.Matches(haystack, needle)) 
    { 
     int startLine = 1, endLine = 1; 
     // You could make it to return false if this fails. 
     // But lets assume the index is within text bounds. 
     if (m.Index < haystack.Length) 
     { 
      for (int i = 0; i <= m.Index; i++) 
       if (Environment.NewLine.Equals(haystack[i])) 
        startLine++; 
      endLine = startLine; 

      for (int i = m.Index; i <= (m.Index + needle.Length); i++) 
       if (Environment.NewLine.Equals(haystack[i])) 
        endLine++; 
     } 

     richTextBox1.Text += string.Format(
"\nFound @ {0} Line {1} to {2}", m.Index, startLine, endLine); 

實際上不會,如果工作針穿過一條線,但那是因爲正則表達式不認識。

編輯也許你可以替換endlines用空格文本並應用正則表達式存在,這個代碼將仍然工作,如果指針在一條線,將仍然可以發現:

Regex.Matches(haystack.Replace(Environment.NewLine, " "), needle)