none
Zahl und Text aus einem Textfeld extrahieren

    Frage

  • Schönen guten Tag,

    ich möchte in einer Access Abfrage aus einem Textfeld immer die gleiche Zahlen und Namenabfolgen extrahieren.
    In meinem Beispiel möchte ich diesen Teil extrahieren:

    18 Mustermann, Max

    Die 18 ist dabei die Trikotnummer

    Natürlich stehen in dem Textfeld unterschiedlichste Namen und die Trikotnummer kann auch einstellig sein.
    In den Vereinsnamen kann, muss aber keine Zahl vorkommen.

    So können die Einträge aussehen:

    Tor durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    2 Minuten Strafe gegen 18 Mustermann, Max (TV 1928 Hummelhausen)
    7-Meter verworfen durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    Disqualifikation gegen 18 Mustermann, Max (TV 1928 Hummelhausen)
    Tor nach 7-Meter durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    Verwarnung gegen 18 Mustermann, Max (TV 1928 Hummelhausen)

    Für Hilfe wäre ich dankbar.
    Montag, 20. November 2017 15:46

Antworten

  • Hi Stefan,
     
    Stefan Falz [MVP] wrote:
     
    > Ich weiß jetzt nicht, ob man in VBA auch Regex
    > verwenden kann aber falls ja, wäre das definitiv die sinnvollere Wahl.
     
    Kann man, siehe Vortrag und Beispiel-DB von Thomas Möller, AEK17, Regular
     
    Gruss - Peter
     
    --
     
    Donnerstag, 23. November 2017 10:38
    Moderator
  • Hi,

    muss es unbedingt in einer Access Abfrage sein? Ich weiß jetzt nicht, ob man in VBA auch Regex verwenden kann aber falls ja, wäre das definitiv die sinnvollere Wahl. Mit einer reinen Access SQL Abfrage wage ich mal zu behaupten, dass das Gewünschte nicht umsetzbar ist.

    Egal, mit welcher Technologie, eine 100%ige Erkennungsrate wirst Du nicht erreichen, wenn die Elemente nicht separat getaggt sind oder es sein kann, dass noch weitere Inhalte, die dem Format entsprechen, im Text vorkommen.

    Wenn man den Nachnamen und den Vornamen als eines sieht (also ggfs. nicht immer ein Komma dazwischensteht, sondern auch mal ein Leerzeichen oder auch gar nichts) würde bspw. ein Regex Ausdruck (mit dem man das schon parsen könnte) auch "2 Minuten" als entsprechende Kombination erkennen.

    Wenn man das Format exakt auf "<Zahl> <Nachname>, <Vorname>" setzen kann, geht es zwar. Aber auch dann darf im Text natürlich auch nichts vorkommen, was diesem Format entspricht.

    In VB.NET könnte das bspw. so aussehen:

    Dim Items As New List( Of String )
        Items.Add( "Tor durch 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "2 Minuten Strafe gegen 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "7-Meter verworfen durch 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "Disqualifikation gegen 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "Tor nach 7-Meter durch 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "Verwarnung gegen 18 Mustermann, Max (TV 1928 Hummelhausen)" )
    
    Dim Regex As New Regex( "(\d{1,2}) (\w*, \w*)", RegexOptions.IgnoreCase Or RegexOptions.Singleline )
        For Each Item As String In Items
    	TextBox1.AppendText( Item & Environment.NewLine )
            For Each Match As Match In Regex.Matches( Item )
    	    TextBox1.AppendText( "Nummer: " & Match.Groups( 1 ).Value & Environment.NewLine )
    	    TextBox1.AppendText( "Name: "   & Match.Groups( 2 ).Value & Environment.NewLine )
    	    TextBox1.AppendText( Environment.NewLine )
            Next
        Next

    Das ergibt dann folgende Ausgabe:

    Tor durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    2 Minuten Strafe gegen 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    7-Meter verworfen durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    Disqualifikation gegen 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    Tor nach 7-Meter durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    Verwarnung gegen 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max

    Ein Beispiel für einen Text, der hier falsche Ergebnisse liefern würde, wäre bspw.:

    Treffer nach 2 Minuten, geworfen durch Abc.

    Hier würde dann als Nummer 2 und als Name "Minuten, geworfen" ausgegeben. Das lässt sich aber nicht verhindern.

    Bei folgendem Text:

    Treffer nach 2 Minuten, geworfen durch 18 Mustermann, Max

    kämen dann zwei Ergebnisse:

    Treffer nach 2 Minuten, geworfen durch 18 Mustermann, Max
    Nummer: 2
    Name: Minuten, geworfen
    
    Nummer: 18
    Name: Mustermann, Max

     


    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





    Montag, 20. November 2017 23:34
    Moderator

Alle Antworten

  • Hi,

    muss es unbedingt in einer Access Abfrage sein? Ich weiß jetzt nicht, ob man in VBA auch Regex verwenden kann aber falls ja, wäre das definitiv die sinnvollere Wahl. Mit einer reinen Access SQL Abfrage wage ich mal zu behaupten, dass das Gewünschte nicht umsetzbar ist.

    Egal, mit welcher Technologie, eine 100%ige Erkennungsrate wirst Du nicht erreichen, wenn die Elemente nicht separat getaggt sind oder es sein kann, dass noch weitere Inhalte, die dem Format entsprechen, im Text vorkommen.

    Wenn man den Nachnamen und den Vornamen als eines sieht (also ggfs. nicht immer ein Komma dazwischensteht, sondern auch mal ein Leerzeichen oder auch gar nichts) würde bspw. ein Regex Ausdruck (mit dem man das schon parsen könnte) auch "2 Minuten" als entsprechende Kombination erkennen.

    Wenn man das Format exakt auf "<Zahl> <Nachname>, <Vorname>" setzen kann, geht es zwar. Aber auch dann darf im Text natürlich auch nichts vorkommen, was diesem Format entspricht.

    In VB.NET könnte das bspw. so aussehen:

    Dim Items As New List( Of String )
        Items.Add( "Tor durch 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "2 Minuten Strafe gegen 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "7-Meter verworfen durch 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "Disqualifikation gegen 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "Tor nach 7-Meter durch 18 Mustermann, Max (TV 1928 Hummelhausen)" )
        Items.Add( "Verwarnung gegen 18 Mustermann, Max (TV 1928 Hummelhausen)" )
    
    Dim Regex As New Regex( "(\d{1,2}) (\w*, \w*)", RegexOptions.IgnoreCase Or RegexOptions.Singleline )
        For Each Item As String In Items
    	TextBox1.AppendText( Item & Environment.NewLine )
            For Each Match As Match In Regex.Matches( Item )
    	    TextBox1.AppendText( "Nummer: " & Match.Groups( 1 ).Value & Environment.NewLine )
    	    TextBox1.AppendText( "Name: "   & Match.Groups( 2 ).Value & Environment.NewLine )
    	    TextBox1.AppendText( Environment.NewLine )
            Next
        Next

    Das ergibt dann folgende Ausgabe:

    Tor durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    2 Minuten Strafe gegen 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    7-Meter verworfen durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    Disqualifikation gegen 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    Tor nach 7-Meter durch 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max
    
    Verwarnung gegen 18 Mustermann, Max (TV 1928 Hummelhausen)
    Nummer: 18
    Name: Mustermann, Max

    Ein Beispiel für einen Text, der hier falsche Ergebnisse liefern würde, wäre bspw.:

    Treffer nach 2 Minuten, geworfen durch Abc.

    Hier würde dann als Nummer 2 und als Name "Minuten, geworfen" ausgegeben. Das lässt sich aber nicht verhindern.

    Bei folgendem Text:

    Treffer nach 2 Minuten, geworfen durch 18 Mustermann, Max

    kämen dann zwei Ergebnisse:

    Treffer nach 2 Minuten, geworfen durch 18 Mustermann, Max
    Nummer: 2
    Name: Minuten, geworfen
    
    Nummer: 18
    Name: Mustermann, Max

     


    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





    Montag, 20. November 2017 23:34
    Moderator
  • Hallo,

    ich denke mal das in einer Abfrage zu kodieren wird schwierig bis unmöglich, aber sicherlich extrem fehleranfällig und unmöglich zu debuggen.

    Mit einer VBA Routine könnte man es ewt. hinbekommen wenn man Regeln finden kann.

    z.B. Steht der Vereinsname immer in Klammer und steht die Trikotnummer immer als letzte Zahl links von Klammer auf?

    Dann kann man eine Funktion schreiben, die den Namen und die Trikotnummer extrahiert.

    1. Finde Position Klammer auf. Position merken.

    2. Lese Zeichenweise von dort nach links bis numerisches Zeichen

    3. Lese weiter nach links bis Leerzeichen. Position merken.

    Mit den beiden Positionen den Teilstring aus dem Text entnehmen.

    Das alles geht unter Verwendung der Befehle Instr, Left, Mid

    Die Funktion kann man dann auch in einer Abfrage verwenden, was aber nicht wirklich schnell ist, wenn es um viele Sätze geht.

    Hope this helps

    Peter

    Montag, 20. November 2017 23:50
  • Hi Stefan,
     
    Stefan Falz [MVP] wrote:
     
    > Ich weiß jetzt nicht, ob man in VBA auch Regex
    > verwenden kann aber falls ja, wäre das definitiv die sinnvollere Wahl.
     
    Kann man, siehe Vortrag und Beispiel-DB von Thomas Möller, AEK17, Regular
     
    Gruss - Peter
     
    --
     
    Donnerstag, 23. November 2017 10:38
    Moderator
  • Ja, das hat super geholfen! Vereinsname steht immer in Klammer und die Trikotnummer tritt immer als letzte Zahl links der Klammer auf. Nachname und Vorname sind immer mit Komma getrennt. Werde es mit dem vorgeschlagenen Versuchsweisen probieren. Vielen Dank!
    Donnerstag, 23. November 2017 10:55