2011-12-11 94 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)