2016-04-27 12 views
4

: Hier ist meine aktuellen Code (21.233.664 Zeichen) istunerwünschte Zeichen entfernen aus einer riesigen EDIT Datei

string str = myInput.Text; 
     StringBuilder sb = new StringBuilder(); 
     foreach (char c in str) 
     { 
      if ((c >= 'a' && c <= 'z') || c == '_' || c==' ') 
      { 
       sb.Append(c); 
      } 
     } 
     output.Text = sb.ToString(); 

Lassen Sie uns sagen, dass ich eine große Textdatei haben, die mit Unterstrichen Sonderzeichen und normale Ausdrücke enthält.

Hier sind ein paar Beispiele für die Saiten, die ich suche:

  • super_test
  • Test
  • another_super_test

Wie Sie sehen können, nur Kleinbuchstaben Buchstaben sind mit Unterstrichen zulässig. Nun, wenn ich diese Zeichenfolge in einer Textdatei, die wie folgt aussieht:

> §> ˜;@ ®> l? super_test D>ÿÿÿÿ “G? tI> €[> €? È 

Das Problem, das ich mit Blick auf bin ist, dass einige einsamen Briefe noch gerettet werden. In dem oben angegebenen Beispiel würde der Ausgang sein:

l super_test t 

Um dieses Zeichen zu erhalten geritten, ich muß die ganze Datei erneut durchlaufen, aber hier ist meine Frage: wie kann ich wissen, ob ein Brief einsam ist oder nicht?

Ich bin mir nicht sicher, ob ich die Möglichkeiten mit Regex verstehe, also wenn mir jemand einen Hinweis geben könnte, würde ich es wirklich schätzen.

+2

Ich denke, es ist ziemlich sicher zu sagen, dass ein Brief einsam ist, wenn es :-) – dasblinkenlight

+0

weint Wie " einsam "reden wir? Sie können Ihrem Regex eine Mindestlänge hinzufügen. – AntiTcb

+0

Wie groß ist "riesig"? Wie machst du die Filterung, die du zeigst? –

Antwort

6

Sie brauchen eindeutig einen regulären Ausdruck. Eine einfache wäre [a-z_]{2,}, die alle Zeichenfolgen von Kleinbuchstaben a bis z Buchstaben und Unterstriche, die mindestens 2 Zeichen lang sind, übernimmt.

Seien Sie vorsichtig, wenn Sie die große Datei analysieren. Da ich riesig bin, stelle ich mir vor, dass Sie eine Art Puffer verwenden. Sie müssen sicherstellen, dass Sie nicht ein halbes Wort in einem Puffer und das andere in der nächsten erhalten.

0

Sie können den Raum nicht wie die anderen zulässigen Zeichen behandeln. Der Platz ist nicht nur akzeptabel, sondern dient auch als Trennzeichen für Ihre eigenen Charaktere. (Dies könnte auch ein Problem mit dem vorgeschlagenen regulären Ausdrücken sein, ich nicht sicher sagen konnte.) Wie auch immer, das tut, was (glaube ich) Sie wollen:

string str = "> §> ˜;@ ®> l? super_test D>ÿÿÿÿ “G? tI> €[> €? È"; 
StringBuilder sb = new StringBuilder(); 
char? firstLetterOfWord = null; 
foreach (char c in str) 
{ 
    if ((c >= 'a' && c <= 'z') || c == '_') 
    { 
     int length = sb.Length; 
     if (firstLetterOfWord != null) 
     { 
      // c is the second character of a word 
      sb.Append(firstLetterOfWord); 
      sb.Append(c); 
      firstLetterOfWord = null; 
     } 
     else if (length == 0 || sb[length - 1] == ' ') 
     { 
      // c is the first character of a word; save for next iteration 
      firstLetterOfWord = c; 
     } 
     else 
     { 
      // c is part of a word; we're not first, and prev != space 
      sb.Append(c); 
     } 
    } 
    else if (c == ' ') 
    { 
     // If you want to eliminate multiple spaces in a row, 
     // this is the place to do so 
     sb.Append(' '); 
     firstLetterOfWord = null; 
    } 
    else 
    { 
     firstLetterOfWord = null; 
    } 
} 

Console.WriteLine(sb.ToString()); 

Es mit Singletons und voller Worten arbeitet bei Anfang und Ende der Zeichenfolge. Wenn Ihre Eingabe etwas wie [email protected] enthält, wird die Ausgabe zusammen ausgeführt (onetwo ohne Leerzeichen). Unter der Annahme, das ist nicht das, was Sie wollen, und auch davon aus, dass Sie keine Notwendigkeit für mehrere Räume in einer Reihe haben:

StringBuilder sb = new StringBuilder(); 
bool previousWasSpace = true; 
char? firstLetterOfWord = null; 
foreach (char c in str) 
{ 
    if ((c >= 'a' && c <= 'z') || c == '_') 
    { 
     if (firstLetterOfWord != null) 
     { 
      sb.Append(firstLetterOfWord).Append(c); 
      firstLetterOfWord = null; 
      previousWasSpace = false; 
     } 
     else if (previousWasSpace) 
     { 
      firstLetterOfWord = c; 
     } 
     else 
     { 
      sb.Append(c); 
     } 
    } 
    else 
    { 
     firstLetterOfWord = null; 
     if (!previousWasSpace) 
     { 
      sb.Append(' '); 
      previousWasSpace = true; 
     } 
    } 
} 

Console.WriteLine(sb.ToString()); 
Verwandte Themen