none
Regex funzt nicht RRS feed

  • Frage

  • Guten Abend,

    nichts zu machen: Regex will nicht mit mir. Aus einer RTB will ich einige Werte auslesen, um sie in einer Tabelle zu speichern.

    1. Blutdruck

    steht immer im Format RR 170/105

    mein Regex: "RR [0-9]{2,3}[/]{1}[0-9]{2,3}" Ich bekomme ein match.Success, aber ich wollte gleichzeitig grobe Tippfehler ausschliessen und falsche Werte nicht weiterverarbeiten. Aber es matcht auch bei 1034/85. Ich dachte, wenn als MIN/MAX 2,3 angegeben ist, dann liefert ein vierstelliger Wert kein Success. Aber das scheint nicht der Fall zu sein.

    2. Größe

    steht immer im Format Gr.: 181 cm

    mein Regex: "Gr.: [0-9]{1,3}" Es ist dasselbe Problem wie oben. Es werden auch vierstellige Werte gefunden. Und am liebsten würde ich auch Werte über 300 cm ausschliessen.

    3. Gewicht

    steht immer im Format Gew.: 75 kg oder 74.7 kg oder 73, 4 kg

    mein Regex: "^Gew.: \d{1,3}([?:\.,]\d{1}){0,1}$" funktioniert überhaupt nicht, trotz stundenlangem Probieren und Verwenden von Beispielen aus dem Netz. Wenn ich das kg weglasse, habe ich noch die besten Ergebnisse.

                If RTBKrk2.Text.Contains("Gew.: ") Then
                    Dim regex As New RegularExpressions.Regex("^Gew.: \d{1,3}([?:\.,]\d{1}){0,1}$")
                    Dim match As RegularExpressions.Match = regex.Match(RTBKrk2.Text)
                    If match.Success Then
                        Dim dummy As String = match.Value
                    End If

    Ich hoffe so sehr, dass mir jemand behilflich sein kann.

    Viele Grüße Norbert


    • Bearbeitet norbert3 Dienstag, 12. November 2019 18:39 Tippfehler
    Dienstag, 12. November 2019 18:37

Antworten

  • Hallo Nobert,

    wie prüfst du deine regulären Ausdrücke?

    Reguläre Ausdrücke arbeiten mit konkreten Werten oder Platzhaltern, die Quantifiziert werden und von links nach rechts abgearbeitet werden (suche nach "Konstruktion eines regulären Ausdrucks" vllt. etwas akademisch). Kleines Beispiel

    "Gr\.:\s*[1-2]{0,1}[0-9]{1,2}[\s\D]+"   Suche nach "Gr.:" gefolgt von bliebigen (* = kein oder beliege Anzahl) von Freiraumzeichen (\s = Tabs oder Spaces). Das nächste Zeichen kann eine eins oder zwei sein ({0,1} kein oder einmal) wiederum gefolgt von zwei beliebigen Ziffern([0-9] kann auch ersatzweise mit \d geschrieben werden). Abschließen muss wieder ein (oder mehrere =+) Freiraumzeichen oder beliegegs Zeichen (keine Ziffern \D) abschließen. Der Ausdruck geht normalerweise zeilenweise vor und ".*" liest z.B. immer die komplete Zeile ein, weil "." für alles steht deshalb "\." für einen konkreten Punkt und * für kein oder beliebig oft.

    Die Plausibilität in einem regulären Ausdruck ist schwierig, darum empfehle ich dir dies in einem extra Schritt durchzuführen. Mir ist auch immer noch unklar ob du Eingaben eines Benutzers prüfts oder ob du die Werte aus einer Datei einliest?

    VG

    Alpecin

    • Als Antwort markiert norbert3 Freitag, 22. November 2019 14:05
    Samstag, 16. November 2019 07:36

Alle Antworten

  • Hallo Norbert,

    1. Blutdruck

    Aber es matcht auch bei 1034/85.

    Wird tatsächlich eine vierstellige Zahl vor dem Schrägstrich als Übereinstimmung anerkannt? Ich habe gerade Deinen regulären Ausdruck ausprobiert und bei mir wird eine vierstellige Zahl vor dem Schrägstrich nicht durchgelassen, dafür aber als zweite Zahl (RR 85/1034). Da ich das von Dir beschriebene Verhalten bei der Eingabe einer vierstelligen Zahl vor dem Schrägstrich in zwei Visual Studio-Versionen nicht reproduzieren konnte, möchte ich Dich fragen, welche Version Du installiert hast und welches .NET Framework als Zielframework ausgewählt ist?

    Um eine vierstellige Zahl als zweite Zahl auszuschließen, füge dem Ausdruck "\z" oder ein Dollarzeichen an.

    2. Größe

    steht immer im Format Gr.: 181 cm

    mein Regex: "Gr.: [0-9]{1,3}" Es ist dasselbe Problem wie oben. Es werden auch vierstellige Werte gefunden.

    Hier könnte auch das Dollarzeichen oder "\z" Abhilfe schaffen, da dadurch keine weiteren Zeichen (also keine vierte Ziffer) zugelassen werden. Da aber Dein Format cm beinhaltet, könntest Du die Maßeinheit ebenfalls in den regulären Ausdruck mit einbeziehen:

    Dim r As New Regex("Gr.: [0-9]{1,3} cm")
    'oder, wenn auf cm nicht geprüft wird:
    'Dim r As New Regex("Gr.: [0-9]{1,3}\z") oder: Dim r As New Regex("Gr.: [0-9]{1,3}$")

    Und am liebsten würde ich auch Werte über 300 cm ausschliessen.

    Sieh Dir dieses Beispiel an:

    Dim r As New Regex("Gr.: ([0-9]{1,2}|[12][0-9]{2}) cm")

    3. Gewicht

    steht immer im Format Gew.: 75 kg oder 74.7 kg oder 73, 4 kg

    mein Regex: "^Gew.: \d{1,3}([?:\.,]\d{1}){0,1}$" funktioniert überhaupt nicht,

    An Deinem regulären Ausdruck gibt es (beinahe) nichts auszusetzen (oder zumindest ist mir nichts aufgefallen). Lediglich das Gewichtsmaß ist im Ausdruck nicht zu finden. Stattdessen stellt das Dollarzeichen sicher, dass nach dem Wort Gew.: und den Zahlen keine weiteren Zeichen vorkommen und vermutlich deshalb bekommst Du ohne Eingabe des Gewichtsmaßes die besten Ergebnisse. Wenn Du auch "kg" mit einbeziehen möchtest, dann probiere es so: "^Gew.: \d{1,3}([?:\.,]\d{1}){0,1} kg". Wenn dies Deinen Anforderungen nicht entspricht, gib bitte ein paar Beispiele für richtige Werte, die nicht durchgelassen warden, oder für falsche, die durchgelassen werden.

    Gruß,
    Dimitar


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Mittwoch, 13. November 2019 15:28
    Moderator
  • Danke Dimitar. Ich bin überglücklich, dass Du Dich mit unserem Problem beschäftigst hast! Regex werde ich nie in meinem Leben begreifen (hab nicht mehr lange ;-).

    Leider komme ich erst morgen dazu, alles nochmal nachzustellen. Vorab nur: das RR, die cm und die kg muss ich später sowieso weg-replacen, da in der Datenbank nur die "nackten" Werte stehen sollen. Aber bei der Eingabe in die RTB brauche ich vorerst noch den gesamten String. Über TextChanged (oder KeyPress - weiss noch nicht) färbe ich den Text gleich etwas ein, wenn die Eingabe plausibel ist und matcht.

    Schöne Grüße Norbert

    Mittwoch, 13. November 2019 16:02
  • So, frisch ans Werk.

    Du hattest Recht: mehr als 3 Stellen vor dem / bei RR matcht nicht, aber

    "xyz RR 180/110 xyz","RR [0-9]{2,3}[/]{1}[0-9]{2,3}"      TRUE
    "xyz RR 180/1111 xyz","RR [0-9]{2,3}[/]{1}[0-9]{2,3}"     TRUE
    "xyz RR 180/110 xyz","RR [0-9]{2,3}[/]{1}[0-9]{2,3}$"     FALSE
    "xyz RR 180/1111 xyz","RR [0-9]{2,3}[/]{1}[0-9]{2,3}$"    FALSE
    "xyz RR 180/110 xyz","RR [0-9]{2,3}[/]{1}[0-9]{2,3}\z"    FALSE
    
    "xyz Gr.: 5555 xyz","Gr.: [0-9]{1,3}"     TRUE
    "xyz Gr.: 555 xyz","Gr.: [0-9]{1,3}$"     FALSE
    "xyz Gr.: 255 xyz","Gr.: ([0-9]{1,2}|[12][0-9]{2})"      TRUE-ist Spitze!!!
    
    "xyz Gew.: 62 kg","^Gew.: \d{1,3}([?:\.,]\d{1}){0,1}$"    FALSE
    "xyz Gew.: 62 kg","Gew.: \d{1,3}([?:\.,]\d{1}){0,1}"      TRUE
    "xyz Gew.: 6210 kg","Gew.: \d{1,3}([?:\.,]\d{1}){0,1}"    TRUE-fatal
    

    Mein VS ist Community 2017 Version 15.9.7

    Framework 4.7.03190

    Viele Grüße Norbert


    • Bearbeitet norbert3 Donnerstag, 14. November 2019 07:55
    Donnerstag, 14. November 2019 07:52
  • Leider treten noch Mängel auf. Größe funktioniert nur, wenn man cm mit angibt. Einige unserer Mitarbeiterinnen machen das. Die anderen müsste ich dazu "verdonnern". Aber da schreien sie gleich wieder nach mehr Lohn ;-)

    Und im match.Value steht nur eine zweistellige Zahl!?

    "xyz Gr.: 5555 xyz","Gr.: ([0-9]{1,2}|[12][0-9]{2})"       TRUE
    "xyz Gr.: 5555 cm xyz","Gr.: ([0-9]{1,2}|[12][0-9]{2}) cm" FALSE
    "xyz Gr.: 255 cm xyz","Gr.: ([0-9]{1,2}|[12][0-9]{2}) cm"  TRUE

    Donnerstag, 14. November 2019 08:28
  • Probier doch folgendes:

    "RR [0-9]{2,3}[/]{1}[0-9]{2,3}[\s|xyz]+"

    "Gr\.: [0-9]{1,3}[\s|xyz]+"

    "Gew\.: \d{1,3}[\s|kg]+"

    um nur die Zahlenwerte zu bekommen mußt du mit Klammern gruppieren und im Regex die entsprechende Gruppe

    auswählen. Beispielsweise so "RR (<Blutdruck>[0-9]{2,3}[/]{1}[0-9]{2,3})[\s|xyz]+"
    der Zugriff erfolgt dann über Match.Groups["Blutdruck"].Value

    VG

    Alpecin


    • Bearbeitet Alpecin Donnerstag, 14. November 2019 08:39
    Donnerstag, 14. November 2019 08:39
  • Danke! Schon sehr nahe dran. RR ist perfekt. Das xyz steht nur für beliebigen Text. Das OR habe ich also weggelassen.

    Kannst Du bei der Größe nur bis 300 matchen? Größer ist wohl keiner.

    Beim Gewicht wird (manchmal) Punkt/Komma verwendet (mein Personal kann sich ohne Zwang da nicht einigen). Dann matcht es aber nicht mehr.

    Viele Grüße Norbert

    Donnerstag, 14. November 2019 09:35
  • Hallo Norbert,

    versuchs mal damit:       "Gew\.: \d{1,3}([.|,]\d){0,1}[\s|kg]+"

    Ich kenn den Programmablauf jetzt nicht, aber die Prüfung ob die Werte plausibel sind würde ich beim Übertragen in die Datenbank machen.

    Alternativ kannst du den folgenden Ausdruck probieren:

    Gr\.: [1-2]{0,1}[0-9]{1,2}[\s|\w]+

    VG

    Alpecin



    • Bearbeitet Alpecin Donnerstag, 14. November 2019 13:32
    Donnerstag, 14. November 2019 09:51

  • Ich kenn den Programmablauf jetzt nicht, aber die Prüfung ob die Werte plausibel sind würde ich beim Übertragen in die Datenbank machen.

    Ja, hab ich auch schon überlegt. Aber es ist ein großer Vorteil, wenn man gleich bei der Eingabe in die RTB ein Feedback bekommt, ob man sich vertippt hat. Das KeyPress ist eh schon drin im Code. Und ein SelectionColor mit Start und Length einzufügen ist kein Thema.

    Deine Regex prüfe ich nachher gleich. Geht im Moment nicht ...

    Donnerstag, 14. November 2019 13:28
  • Gewicht mit Punkt oder Komma jetzt tadellos. Danke!!!

    "xyz Gr\.: 180 cm","Gr\.: [1-2]{0,1}[0-9]{1,2}[\s|\w]+"    FALSE ! muss aber True sein

    Ich prüfe mit der Routine in meinem ersten Beitrag.

    Donnerstag, 14. November 2019 14:36
  • Hallo Norbert,

    du mußt nur den Backslash in "xyz Gr\.: 180 cm" entfernen dann matched es oder

    im Regex folgendes schreiben "Gr\\\.: [1-2]{0,1}[0-9]{1,2}[\s|\w]+"

    Der Ausdruck "\." sucht nach einem Punkt. Der Punkt muß escaped werden,

    weil der im Regex ansonsten für ein beliebiges Zeichen steht. Außerdem kannst du evtl.

    die Fehlertoleranz erhöhen wenn du folgenden Ausdruck verwendest:

    "Gr\.:\s*[1-2]{0,1}[0-9]{1,2}[\s|\w]+"

    VG

    Alpecin


    • Bearbeitet Alpecine Freitag, 15. November 2019 07:56
    Freitag, 15. November 2019 07:55
  • Leider immer noch nicht. Wenn die Experten auch nicht gleich zum Ziel kommen, ist es nicht verwunderlich, dass ich als Laie das wohl niemals hinbekommen kann ;-)

    Hier Deine 2 Beispiele mit zweimal falschem Ergebnis:

    "xyz Gr.: 180 ","Gr\\\.: [1-2]{0,1}[0-9]{1,2}[\s|\w]+"      FALSE

    "xyz Gr.: 3180 ","Gr.:\s*[1-2]{0,1}[0-9]{1,2}[\s|\w]+"    TRUE (so groß ist sicher niemand)

    Und es wäre schön, wenn Größe über 3 Meter (301 cm) FALSE ergeben würde.

    Viele Grüße Norbert

    Freitag, 15. November 2019 09:00
  • Hallo Norbert,

    um dir Abschließend zu Helfen müsstest du eine komplette Aufstellung machen was matchen soll und was nicht.
    Du kommst bei jedem Post mit neuen Ausdrücken rüber.
    Ich weiß zum Beispiel nicht soll jetzt "xyz Gr\.: 180 cm" jetzt matchen oder nicht.

    Außerdem weiß ich nicht genau für was "xyz" steht. Ist xyz gemeint oder sind das Platzhalter für irgendwelche Zeichen (Buchstaben oder Ziffern oder beides oder sonstige Zeichen).

    Für "xyz Gr.: 3180 " müsste dann Gr\.:\s*[1-2]{0,1}[0-9]{1,2}[\s\D]+ funzen.

    Ansonsten schau doch mal unter http://www.regexe.de/hilfe.jsp 

    VG

    Alpecin


    Freitag, 15. November 2019 16:11
  • Hallo Alpecine,

    es tut mir aufrichtig leid, dass ich so nerve. Und ich habe die größte Hochachtung vor Deinen Kenntnissen und bin voller Dankbarkeit, dass Du Deine Zeit für uns opferst.

    Wie ich oben schon geschrieben habe

    Das xyz steht nur für beliebigen Text

    Der kann da sein, RR kann aber auch am Anfang der RTB oder am Schluss sein. D.h. RR xxx kann allein stehen oder in anderen Text eingebettet sein (natürlich immer Leerstellen vorhanden). Das gilt auch für Größe und Gewicht.

    Matchen muss:

    RR 70/50 und RR 180/90 und RR 180/120 und RR 210/90 und RR210/140

    und ich brauche in Value den Wert (ohne das RR), aber das muss ich später replacen. Gilt auch für Gr.: und Gew.:

    Nicht matchen sollten Werte vor und hinter dem Slash über 400.

    Matchen muss:

    Gr.: 10 und Gr.: 120 und Gr.: 210

    Es werden keine Dezimalstellen eingetippt, sondern ich muss später beim Speichern in die DB runden. Nicht matchen sollten Werte über 300 (kann jemand über 300 cm groß sein?). Kann wieder eingebettet sein in Text (Leerzeichen natürlich vorhanden).

    Matchen muss:

    Gew.: 2 und Gew.: 10 und Gew.: 10,2 und Gew.: 10.2 und Gew.: 70 und Gew.: 70,2 und Gew.: 70.2 und Gew.: 168 usw.

    kg dahinter (durch Leerzeichen getrennt) kann vorkommen, ist ja dann aber wie normaler Text und muss nicht mit ins regex. Nicht matchen sollten Werte über 400. Hab noch keinen Patienten mit über 400 kg gesehen ;-) Wohl aber Fehl/Frühgeburt mit 1,5 kg

    Wir würden uns sehr freuen, wenn Du noch ein bisserl durchhältst ...

    Schöne Grüße Norbert




    • Bearbeitet norbert3 Freitag, 15. November 2019 18:58
    Freitag, 15. November 2019 18:51
  • Hab mindestens schon 14 Stunden die Grundlagen studiert. Komme einfach nicht dahinter ...
    Freitag, 15. November 2019 18:58
  • Hallo Nobert,

    wie prüfst du deine regulären Ausdrücke?

    Reguläre Ausdrücke arbeiten mit konkreten Werten oder Platzhaltern, die Quantifiziert werden und von links nach rechts abgearbeitet werden (suche nach "Konstruktion eines regulären Ausdrucks" vllt. etwas akademisch). Kleines Beispiel

    "Gr\.:\s*[1-2]{0,1}[0-9]{1,2}[\s\D]+"   Suche nach "Gr.:" gefolgt von bliebigen (* = kein oder beliege Anzahl) von Freiraumzeichen (\s = Tabs oder Spaces). Das nächste Zeichen kann eine eins oder zwei sein ({0,1} kein oder einmal) wiederum gefolgt von zwei beliebigen Ziffern([0-9] kann auch ersatzweise mit \d geschrieben werden). Abschließen muss wieder ein (oder mehrere =+) Freiraumzeichen oder beliegegs Zeichen (keine Ziffern \D) abschließen. Der Ausdruck geht normalerweise zeilenweise vor und ".*" liest z.B. immer die komplete Zeile ein, weil "." für alles steht deshalb "\." für einen konkreten Punkt und * für kein oder beliebig oft.

    Die Plausibilität in einem regulären Ausdruck ist schwierig, darum empfehle ich dir dies in einem extra Schritt durchzuführen. Mir ist auch immer noch unklar ob du Eingaben eines Benutzers prüfts oder ob du die Werte aus einer Datei einliest?

    VG

    Alpecin

    • Als Antwort markiert norbert3 Freitag, 22. November 2019 14:05
    Samstag, 16. November 2019 07:36
  • Danke! Die Eingabe in  die RichTextBox erfolgt durch Eintippen. Da kommen mitunter auch längere Texte (bis 500 Zeichen) vor. Dann erfolgt das Speichern des gesamten Rtf in eine MySql DB. Den umgekehrten Weg (Lesen aus der DB und Darstellung in der RTB) gibt es natürlich auch.

    Beim Eintippen will ich im TextChanged-Handle in Echtzeit prüfen, ob RR, Gr.: und Gew.: mit plausiblen Werten vorhanden sind. Wenn ja, dann färbe ich diesen Text ein. So merkt der Anwender gleich, ob die Eingabe korrekt war oder er sich vielleicht vertippt hat. Rückwärts (Lesen aus der DB und Darstellung in der RTB) würde ich es auch so machen wollen.

    Deine Erklärungen habe ich 10 mal durchgelesen und auch einiges probiert. Danke für Deine Mühe! Aber ich habe mein Ziel dennoch nicht erreichen können. Plausibilität wäre gegeben, wenn z.B. Blutdruckwerte nicht vierstellig sind oder die Größe nicht über 300 cm liegt. Ist das im Regex wirklich nicht möglich (Größe nicht vierstellig und bei dreistellig erste Ziffer nur 1 oder 2, bei zwei- und einstellig alle Ziffern erlaubt)? Oder bin ich zu dusselig dafür ...


    • Bearbeitet norbert3 Sonntag, 17. November 2019 07:13
    Samstag, 16. November 2019 11:01
  •  Ist das im Regex wirklich nicht möglich (Größe nicht vierstellig und bei dreistellig erste Ziffer nur 1 oder 2, bei zwei- und einstellig alle Ziffern erlaubt)? Oder bin ich zu dusselig dafür ...

    Genau das müsste doch der Ausdruck "Gr\.:\s*[1-2]{0,1}[0-9]{1,2}[\s\D]+" für die Größe leisten!?


    • Bearbeitet Alpecine Sonntag, 17. November 2019 07:25
    Sonntag, 17. November 2019 07:24
  • Danke! Hat leider nicht geholfen.

    Dim regex As New RegularExpressions.Regex("Gr\.:\s*[1-2]{0,1}[0-9]{1,2}[\s\D]+")
    Dim match As RegularExpressions.Match = regex.Match("das ist ein text Gr.: 240 weiterer Text")

    In match.Value steht dann

    Gr.: 240 weiterer Text

    d.h. der Wert selbst wird nicht separiert. Sorry ...

    Viele Grüße Norbert

    Sonntag, 17. November 2019 12:06
  • Hallo Norbert,

    Regex ist mir persönlich für diese Aufgabe zu komplex, aber falls du nicht auf "Regex" bestehst, kannst du die Sache vielleicht auch anders angehen. Eine Möglichkeit wäre wie in der folgenden Konsolen-App dargestellt:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace TextChecker {
      class Program {
    
        static void Main(string[] args) {
          string testString = "Das ist ein text Gr.: 1240 weiterer Text, der RR 179/187 und Gew.: 519";
          var results = testString.CheckIt();
          if (results.Count > 0) {
            Console.WriteLine("Fehler gefunden!");
            foreach (var kvp in results) {
              Console.WriteLine($"{kvp.Key} = {kvp.Value}");
            }
          } else {
            Console.WriteLine("Alles ok");
          }
          Console.ReadKey();
        }
      }
    
      public static class MyStringExtensions {
        const int SYST_MIN = 0;
        const int SYST_MAX = 300;
        const int DIAS_MIN = 0;
        const int DIAS_MAX = 200;
        const int GEW_MIN = 0;
        const int GEW_MAX = 400;
        const int GR_MIN = 0;
        const int GR_MAX = 300;
        public static List<(string Key, string Value)> CheckIt(this string input) {
          #region Helper...
          bool Checker(string match, string value) {
            switch (match.ToLower()) {
              case "rr":
                return CheckBlutdruck(value, (SYST_MIN, SYST_MAX), (DIAS_MIN, DIAS_MAX));
              case "gr.:":
                return CheckGröße(value, GR_MIN, GR_MAX);
              case "gew.:":
                return CheckGewicht(value, GEW_MIN, GEW_MAX);
              default:
                return true;
            }
          }
          bool CheckBlutdruck(string i,
            (int min, int max) systolisch,
            (int min, int max) diastolisch) {
            try {
              string[] sd = i.Split('/');
              if (sd.Length != 2) return false;
              bool oks = Int32.TryParse(sd[0], out int sys);
              bool okd = Int32.TryParse(sd[1], out int dia);
              return oks && okd &&
                sys > systolisch.min && sys < systolisch.max &&
                dia > diastolisch.min && dia < diastolisch.max &&
                sys > dia;
            } catch (Exception) {
              return false;
            }
          }
          bool CheckGröße(string i, int min, int max) {
            bool ok = Int32.TryParse(i, out int o);
            return ok && o > min && o < max;
          }
          bool CheckGewicht(string i, int min, int max) {
            bool ok = Int32.TryParse(i, out int o);
            return ok && o > min && o < max;
          }
          #endregion
    
          List<string> token = input
            .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
            .ToList();
    
          return token
            .Zip(token.Skip(1), (x, y) => (x, y))
            .Where(p => !Checker(p.x, p.y))
            .ToList();
    
        }
      }
    }

    Das Ganze habe ich mal als Erweiterungsmethode dargestellt.

    Hier kannst du auch konkrete Grenzwerte festlegen/anpassen (s. Konstanten). Die Testmethode funktioniert nur dann, wenn zwischen Gr.:, Gew.: und RR und den zugehörigen Werten ein Leerzeichen ist, wie du es ja in deinem ersten Post auch dargestellt hast.

    Die Methode gibt eine Liste suspekter Ergebnisse zurück, ist die Liste "leer", ist alles okay.

    Ist jetzt nicht ausführlich getestet, ...

    Gruß


    Sonntag, 17. November 2019 20:26
  • Hallo Norbert,

    für diesen Fall gibts dann wie ich bereits weiter oben geschrieben habe die Gruppierung in den regulären Audrücken:

    "Gr\.:\s*(?<Groesse>[1-2]{0,1}[0-9]{1,2})[\s\D]"

    ansonsten würde ich auch vorschlagen auf reguläre Ausdrücke zu verzichten zu das zu Fuß parsen.

    VG

    Alpecin


    • Bearbeitet Alpecin Montag, 18. November 2019 06:17
    Montag, 18. November 2019 06:17
  • @ K. Pater:

    Vielen Dank für den Code! Ist ja ein Riesenaufwand. Ich hätte an sowas tagelang gesessen ...

    Ich werde es wohl bei der Minimalvariante belassen. Value (ob Grösse über 300 oder Gewicht über 400) lässt sich dann schnell abprüfen (evt. sogar mit einem Insert-Update-Trigger beim Schreiben in die Tabelle). So kann ich die Vorzüge von Regex trotzdem nutzen und muss nicht soviel Code schreiben für das "zu Fuß parsen".

                If RTBKrk2.Text.Contains("RR ") Then
                    Dim value As String = MatchRichTextBox1Text("RR [0-9]{2,3}[/]{1}[0-9]{2,3}").Replace("RR ", "")
                    If value <> "" Then UpdateT502("5100", value)
                End If
                If RTBKrk2.Text.Contains("Gr.: ") Then
                    Dim value As String = MatchRichTextBox1Text("Gr.: ([0-9]{1,3}|[1-3][0-9]{2})").Replace("Gr.: ", "")
                    If value <> "" Then UpdateT502("5101", value)
                End If
                If RTBKrk2.Text.Contains("Gew.: ") Then
                    Dim value As String = MatchRichTextBox1Text("Gew\.: \d{1,3}([.|,]\d){0,1}").Replace("Gew.: ", "")
                    If value <> "" Then UpdateT502("5102", value)
                End If
    
        Private Function MatchRichTextBox1Text(regx As String) As String
            Dim color As Color = RTBKrk2.BackColor
            Dim regex As New RegularExpressions.Regex(regx)
            Dim match As RegularExpressions.Match = regex.Match(RTBKrk2.Text)
            If match.Success Then
                RTBKrk2.SelectionStart = RTBKrk2.Text.IndexOf(match.Value)
                RTBKrk2.SelectionLength = match.Value.Length
                RTBKrk2.SelectionBackColor = Color.LightGreen
                RTBKrk2.SelectionStart = RTBKrk2.TextLength
                RTBKrk2.SelectionBackColor = color
                Return match.Value
            End If
            Return ""
        End Function
    
        Private Sub UpdateT502(kenn As String, val As String)
            iDBS.UpdateTable("INSERT INTO t502 VALUES('" & kenn & "','" & val & "','" & CDate(tbKrkDatum.Text).ToString("yyyy-MM-dd") & "'," &
                             Fall.linknummer & ") ON DUPLICATE KEY UPDATE GDT02='" & val & "',GDT03='" & CDate(tbKrkDatum.Text).ToString("yyyy-MM-dd") & "'")
        End Sub
    

    Nochmals vielen Dank an alle und schöne Grüße

    Norbert

    Montag, 18. November 2019 10:49