none
Textdatei nach Wörtern suchen und in eine Tabelle einfügen (C#) RRS feed

  • Frage

  • Hallo,

    ich wollte wissen ob es möglich ist einen bestimmten Text aus einer Textdatei auszulesen und diese in eine Tabelle einzutragen.

    z.B. in meinem Text steht irgendwo der Satz :Paul kauft 333 Tomaten: Diesen Satz würde ich gern zerlegen und in einer bestimmten Form wieder in einem WPF-Programm in eine Tabelle einfügen, z.B.

    Name    Aktion    Anzahl   Artikel
    Paul    kauft     333      Tomaten
    
    Wenn ja würde ich gern wissen, wie ich das Ganze angehen kann.
    Donnerstag, 28. März 2013 12:04

Antworten

  • Hallo Tom,

    generell wäre das bspw. so möglich:

    string Dateiinhalt = System.IO.File.ReadAllText( @"F:\temp\Test5.txt" );
    List<string> Worte = Dateiinhalt.Split( new string[] { " " }, StringSplitOptions.RemoveEmptyEntries ).ToList();
    

    Die Variable "Worte" (also eine List<string>) kannst Du dann als Datenquelle für deine Ausgabe verwenden.



    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort markiert TomSteiner Samstag, 30. März 2013 08:47
    Donnerstag, 28. März 2013 12:17
    Moderator
  • Hallo, du musst nur die einzelknen Wörter durchgehen und entsprechend in die TextBox ausgeben (Text-Eigenschaft).

    Durchitterieren kannst du die Liste am besten mit foreach. Was vielleicht auch noch hilft ist wenn du den Dateiinhalt vorher an den Zeilenumbrüchen aufsplittest und dann durchgehst. So dass du wirklich einzelne "Sätze" hast.

    Ein Beipiel mit der Ausgabe in eine TextBox:

                string file = @"...";//Dateipfad
                string[] lines = File.ReadAllLines(file);//Alle Zeilen in Array einlesen
                StringBuilder sb = new StringBuilder(); //StringBuilder zum zusammenbauen der Tabelle im TextFormat
    sb.Append("Name\tAnzahl\tAktion\tArtikel");//Überschriften foreach(string line in lines)//Alle Zeilen durchgehen { string[] words = line.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);//In einzelne Wörter aufsplitten foreach(string word in words) { sb.Append(word);//Wort sb.Append("\t");//Tab } sb.AppendLine(); } textBox1.Text = sb.ToString();//Text ausgeben


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.


    Dienstag, 2. April 2013 13:41
    Moderator
  • Dafür kannst du die StartsWith bzw. EndsWith Methode nutzen. Du musst dann nur jede Zeile nach den beiden : abfragen:
                string file = @"...";//Dateipfad
                string[] lines = File.ReadAllLines(file);//Alle Zeilen in Array einlesen
                StringBuilder sb = new StringBuilder(); //StringBuilder zum zusammenbauen der Tabelle im TextFormat
                    sb.Append("Name\tAnzahl\tAktion\tArtikel");//Überschriften
                foreach(string line in lines)//Alle Zeilen durchgehen
                {
                    if(line.StartsWith(":") && line.EndsWith(":"))
                        continue;//zum nächsten Schleifendurchgang
                    string[] words = line.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);//In einzelne Wörter aufsplitten
                    foreach(string word in words)
                    {
                        sb.Append(word);//Wort
                        sb.Append("\t");//Tab
                    }
                    sb.AppendLine();
                }
                textBox1.Text = sb.ToString();//Text ausgeben
    PS: Es gibt natürlich noch alternativen, wie bspws. folgende:
    if(line.First() == ':' && line.Last() == ':')
        continue;
    usw...


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.


    Mittwoch, 3. April 2013 13:08
    Moderator
  • Die Position eines Textes kann man mit IndexOf ermitteln. Ein fiktives Beipiel dazu:
                string t = "Test 123 Text 456 Test 789";
                string s = t.Substring(//Teilstring erstellen
                    t.IndexOf("456") //Position ermitteln
                    + 3//Länge des Suchtextes aufrechnen
                    ).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)//Aufsplitten
                    .First();//erstes Element auswählen
                //s = "Test"


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.

    • Als Antwort markiert TomSteiner Samstag, 6. April 2013 08:56
    Freitag, 5. April 2013 17:05
    Moderator
  • Ok, das ist nicht ganz einfach da es 1. recht Komplex und 2. nicht gerade einheitlich ist. Meine Idee wäre jetzt jede "Aktion" einzeln zu parsen:
                string content = "”  Ô  &  |  °  Ø    :  z  Í   51330053102B::Raena Aerlin setzt Gewaltiger Schuss ein.513300531329::  ⇒ Die Stechmücke erleidet 18 Punkte Schaden.513300531329::Wynn Reborn trifft den Forst-Fungus und verursacht 10 Punkte Schaden.51330053122E::Niu Snowglare trifft die Stechmücke und verursacht 11 Punkte Schaden.51330053102B::Nezi Nezi setzt Finte ein.513300531329::  ⇒ Der Marienkäfer erleidet 12 Punkte Schaden.51330053132F::  ⇒ Der Marienkäfer erleidet den Effekt von Gemach.51330053102B::Shiina Nightmoon setzt Schattenschuss ein.513300531329::  ⇒ Die Stechmücke erleidet 20 Punkte Schaden.51330053132F::  ⇒ Die Stechmücke erleidet den Effekt von Blind.51330053102B:";
                string[] ds = content.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);//Einzelne Datensätze aufspalten
                Dictionary<string, int> dict = new Dictionary<string, int>();//Dictionary mit Namen und Punkten
                foreach (string d in ds)
                {
                    if (d.Contains("setzt Gewaltiger Schuss ein"))//Aktion Typ 1
                    {
                        string t = d.Substring(0, d.IndexOf("setzt Gewaltiger Schuss ein")).Trim();//Namen heraus bekommen
                        if (dict.ContainsKey(t))
                            dict[t] += 1;//1 Punkt vergeben
                        else
                            dict.Add(t, 1);//Neuen Spieler hinzufügen
                    }
                    else if (d.Contains(" erleidet ") && d.Contains(" Punkte Schaden"))//Aktion Typ 2
                    {
                        string t = d.Substring(0, d.IndexOf("erleidet")).Trim();//Namen heraus bekommen
                        int p = int.Parse(d.Substring(d.IndexOf("erleidet") + 8/*Länge von "erleidet"*/, d.IndexOf(" Punkte Schaden") - d.IndexOf("erleidet") - 8).Trim());
                        if (dict.ContainsKey(t))
                            dict[t] += p;//1 Punkt vergeben
                        else
                            dict.Add(t, p);//Neuen Spieler hinzufügen
                    }
                    //else if...//und immer so weiter...
                    else
                    {
                        //Fehlerhafter Datensatz
                    }
                }
    Wichtig ist hier das man möglichst genau alles abfragt. Unter umständen eignet sich dafür Regex besser.

    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.

    • Als Antwort markiert TomSteiner Montag, 8. April 2013 19:46
    Montag, 8. April 2013 15:43
    Moderator

Alle Antworten

  • Hallo Tom,

    generell wäre das bspw. so möglich:

    string Dateiinhalt = System.IO.File.ReadAllText( @"F:\temp\Test5.txt" );
    List<string> Worte = Dateiinhalt.Split( new string[] { " " }, StringSplitOptions.RemoveEmptyEntries ).ToList();
    

    Die Variable "Worte" (also eine List<string>) kannst Du dann als Datenquelle für deine Ausgabe verwenden.



    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort markiert TomSteiner Samstag, 30. März 2013 08:47
    Donnerstag, 28. März 2013 12:17
    Moderator
  • wie bekomme ich das dann in eine TextBox?

    Dienstag, 2. April 2013 13:25
  • Hallo, du musst nur die einzelknen Wörter durchgehen und entsprechend in die TextBox ausgeben (Text-Eigenschaft).

    Durchitterieren kannst du die Liste am besten mit foreach. Was vielleicht auch noch hilft ist wenn du den Dateiinhalt vorher an den Zeilenumbrüchen aufsplittest und dann durchgehst. So dass du wirklich einzelne "Sätze" hast.

    Ein Beipiel mit der Ausgabe in eine TextBox:

                string file = @"...";//Dateipfad
                string[] lines = File.ReadAllLines(file);//Alle Zeilen in Array einlesen
                StringBuilder sb = new StringBuilder(); //StringBuilder zum zusammenbauen der Tabelle im TextFormat
    sb.Append("Name\tAnzahl\tAktion\tArtikel");//Überschriften foreach(string line in lines)//Alle Zeilen durchgehen { string[] words = line.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);//In einzelne Wörter aufsplitten foreach(string word in words) { sb.Append(word);//Wort sb.Append("\t");//Tab } sb.AppendLine(); } textBox1.Text = sb.ToString();//Text ausgeben


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.


    Dienstag, 2. April 2013 13:41
    Moderator
  • Ok deine Antwort hat mir jetzt schon mal sehr geholfen.

    nun ist mir aufgefallen das in meiner Text Datei zwischen den setzen, die mich interessieren zeug steht was ich nicht brauche und alle setze die für mich interessant sind beginnen mit einem ":"  und enden mit einem ":"  wie müsste ich das abändern das er mir nur diese Sätze in mein Textfeld schreibt.  

    Mittwoch, 3. April 2013 12:59
  • Dafür kannst du die StartsWith bzw. EndsWith Methode nutzen. Du musst dann nur jede Zeile nach den beiden : abfragen:
                string file = @"...";//Dateipfad
                string[] lines = File.ReadAllLines(file);//Alle Zeilen in Array einlesen
                StringBuilder sb = new StringBuilder(); //StringBuilder zum zusammenbauen der Tabelle im TextFormat
                    sb.Append("Name\tAnzahl\tAktion\tArtikel");//Überschriften
                foreach(string line in lines)//Alle Zeilen durchgehen
                {
                    if(line.StartsWith(":") && line.EndsWith(":"))
                        continue;//zum nächsten Schleifendurchgang
                    string[] words = line.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);//In einzelne Wörter aufsplitten
                    foreach(string word in words)
                    {
                        sb.Append(word);//Wort
                        sb.Append("\t");//Tab
                    }
                    sb.AppendLine();
                }
                textBox1.Text = sb.ToString();//Text ausgeben
    PS: Es gibt natürlich noch alternativen, wie bspws. folgende:
    if(line.First() == ':' && line.Last() == ':')
        continue;
    usw...


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.


    Mittwoch, 3. April 2013 13:08
    Moderator
  • Hallo und danke nochmal für die super Hilfe.

    ich hab aber schon wieder eine frage kann ich auch einfach aus der Text Datei nach bestimmten setzten suchen und dann das Wort davor oder den wert danach ausgeben?

    z.B.  wenn der Satz Bernd Meier wirft den Speer 70 Meter weit.

    könnte man doch nach "wirft den Speer" suchen und wenn dies im Text gefunden wurde mir ein Wort

    weiter vorn den Nachnamen und 2 Worte weiter vorn den Vornamen und den wert danach z.B. in ein

    Textfeld eintragen

    wer das so möglich?

    Freitag, 5. April 2013 16:58
  • Die Position eines Textes kann man mit IndexOf ermitteln. Ein fiktives Beipiel dazu:
                string t = "Test 123 Text 456 Test 789";
                string s = t.Substring(//Teilstring erstellen
                    t.IndexOf("456") //Position ermitteln
                    + 3//Länge des Suchtextes aufrechnen
                    ).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)//Aufsplitten
                    .First();//erstes Element auswählen
                //s = "Test"


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.

    • Als Antwort markiert TomSteiner Samstag, 6. April 2013 08:56
    Freitag, 5. April 2013 17:05
    Moderator
  • Ein kleines Problem hab ich noch da Test 123 und Test 789 in meiner Textdatei nicht bekannt sind funktioniert das mit der Positionsangabe nicht ganz

    z.B. wenn ich nach Text suche und den wert -4 angebe kommen die zahlen 123 aber wenn meine zahl länger ist ( was ich ja nicht weis ) bringt es mir alles durcheinander.

    man müsste von Wort zu Wort springen oder von den Lehrzeichen zwischen den Wörtern .

    aber wie?

    Montag, 8. April 2013 07:54
  • Du kannst in meinem Beipielstring natürlich auch nach "Text" suchen, das entspricht auch eher deinen Anforderungen. Dann bekommst du auch entsprechend die Position der 1. Zahl. Mein Beipiel auf deinen vorgegebenen Satz bezogen:
                string t = "Bernd Meier wirft den Speer 70 Meter weit.";
                string search = "wirft den Speer";
                string s = t.Substring(//Teilstring erstellen
                    t.IndexOf(search) //Position ermitteln
                    + search.Length//Länge des Suchtextes aufrechnen
                    ).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)//Aufsplitten
                    .First();//erstes Element auswählen
                //s = "70"

    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.

    Montag, 8. April 2013 10:45
    Moderator
  • aber das ist doch dann fast das selbe oder versteh ich das jetzt falsch

    wenn ich nach wirft den Speer suche und ich möchte das was vor dem Teilstring steht haben (Bernd Meier)und das was nach dem String steht (70) beides sind aber Elemente deren Größe ich aber vorher nicht weis an die 70 zu kommen ist da vielleicht nicht das Problem da diese direkt nach wirft den Speer kommt aber wie komme ich an die Position von Bernd oder Meier (oder weit) wenn ich die länge der worte nicht weis ?

    oder bin ich jetzt schon wirr im Kopf  


    • Bearbeitet TomSteiner Montag, 8. April 2013 11:28
    Montag, 8. April 2013 11:26
  • Die Texte müssen eine eindeutige Syntax haben um sie ordentlich auslesen zu können. "Bernd Maier" steht direkt am Anfang, so hätte man den Startpunkt, den Endpunkt der Zeichenkette kannst du dann wieder per IndexOf("wirft den Speer") finden.

    "weit" steht nun am Ende, das wäre die erste Möglichkeit. Eine 2. wäre das "Meter" hinter der 70 zu erkennen und zu ignorieren und das Wort danach zu nehmen.

    Für den einen Beipielsatz gibts viele Möglichkeiten. Wenn es noch nicht so klappt wie du es willst, dann zeige mal ein paar mehr Datensätze die in das Schema passen müssen.

    PS: Die Methoden trim, trimstart und TrimEnd können Zeichen von den Rändern der Zeichenkette entfernen, bspws. Zeichenkette.
    Weiterhin kann die Split-Methode den String an einem Zeichen aufsplitten, so kannst du einzelne Wörter ermitteln.


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.

    Montag, 8. April 2013 11:31
    Moderator
  • hier mal ein stück des Datensatzes eigentlich soll das ganze ein Dmg Parser werden ich wollte z.B. nach

    "setzt Gewaltiger Schuss ein" suchen und wollte dann gern den Namen () und den Schaden(18) den sie an "" ausgeben so das man das später zusammen zählen kann wer was und wie viel an welchem Gegner gemacht hat.


    • Bearbeitet TomSteiner Dienstag, 9. April 2013 13:48 daten rechtliche gründe
    Montag, 8. April 2013 13:33
  • Ok, das ist nicht ganz einfach da es 1. recht Komplex und 2. nicht gerade einheitlich ist. Meine Idee wäre jetzt jede "Aktion" einzeln zu parsen:
                string content = "”  Ô  &  |  °  Ø    :  z  Í   51330053102B::Raena Aerlin setzt Gewaltiger Schuss ein.513300531329::  ⇒ Die Stechmücke erleidet 18 Punkte Schaden.513300531329::Wynn Reborn trifft den Forst-Fungus und verursacht 10 Punkte Schaden.51330053122E::Niu Snowglare trifft die Stechmücke und verursacht 11 Punkte Schaden.51330053102B::Nezi Nezi setzt Finte ein.513300531329::  ⇒ Der Marienkäfer erleidet 12 Punkte Schaden.51330053132F::  ⇒ Der Marienkäfer erleidet den Effekt von Gemach.51330053102B::Shiina Nightmoon setzt Schattenschuss ein.513300531329::  ⇒ Die Stechmücke erleidet 20 Punkte Schaden.51330053132F::  ⇒ Die Stechmücke erleidet den Effekt von Blind.51330053102B:";
                string[] ds = content.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);//Einzelne Datensätze aufspalten
                Dictionary<string, int> dict = new Dictionary<string, int>();//Dictionary mit Namen und Punkten
                foreach (string d in ds)
                {
                    if (d.Contains("setzt Gewaltiger Schuss ein"))//Aktion Typ 1
                    {
                        string t = d.Substring(0, d.IndexOf("setzt Gewaltiger Schuss ein")).Trim();//Namen heraus bekommen
                        if (dict.ContainsKey(t))
                            dict[t] += 1;//1 Punkt vergeben
                        else
                            dict.Add(t, 1);//Neuen Spieler hinzufügen
                    }
                    else if (d.Contains(" erleidet ") && d.Contains(" Punkte Schaden"))//Aktion Typ 2
                    {
                        string t = d.Substring(0, d.IndexOf("erleidet")).Trim();//Namen heraus bekommen
                        int p = int.Parse(d.Substring(d.IndexOf("erleidet") + 8/*Länge von "erleidet"*/, d.IndexOf(" Punkte Schaden") - d.IndexOf("erleidet") - 8).Trim());
                        if (dict.ContainsKey(t))
                            dict[t] += p;//1 Punkt vergeben
                        else
                            dict.Add(t, p);//Neuen Spieler hinzufügen
                    }
                    //else if...//und immer so weiter...
                    else
                    {
                        //Fehlerhafter Datensatz
                    }
                }
    Wichtig ist hier das man möglichst genau alles abfragt. Unter umständen eignet sich dafür Regex besser.

    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
    Einen Konverter zwischen C# und VB.NET Code gibt es hier.

    • Als Antwort markiert TomSteiner Montag, 8. April 2013 19:46
    Montag, 8. April 2013 15:43
    Moderator
  • vielen dank damit kann ich mich auf jeden fall erst mal ne weile beschäftigen 
    Montag, 8. April 2013 19:48
  • Regex ist super! danke nochmal

    Mittwoch, 10. April 2013 10:00