2011-12-11 6 views
6

utilizo este código para comprobar si una cadena existe en un archivo de texto que he cargado en la memoriaobtener el número de línea para el patrón emparejado

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

La expresión regular devuelve las posiciones donde se produjo un partido pero quiero a saber el numero de linea?

Respuesta

5

La mejor La solución sería llamar a un método que obtiene el número de línea solo si ocurre una coincidencia. De esta forma, el rendimiento no se verá muy afectado si se comprueban varios archivos y la expresión regular con \n funcionará. Encontrado este método en algún lugar de stackoverflow:

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

Se puede dividir el texto en líneas primera y aplicar su expresión regular para cada línea - por supuesto que no funciona si needle contiene una nueva línea:

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

creo que una opción mucho más atractiva sería utilizar un 'StringReader' para el pajar y usar' ReadLine() 'para leer las líneas en lugar de dividir esa manera. –

+0

cierto - Yo había asumido que 'haystack' ya está cargado en la memoria, si no es así, para los archivos más largos absolutamente' File.ReadLines() 'sería preferido – 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); 

realidad no va a funcionar si el aguja cruza una línea, pero eso es porque la expresión regular no reconoce eso.

Editar tal vez usted puede reemplazar las líneas de fondo en el texto con espacios y aplicar la expresión regular allí, este código todavía iba a funcionar y si la aguja cae sobre una línea que todavía se encuentran:

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