RegEx Verständnisproblem

  • Allgemein

Es gibt 29 Antworten in diesem Thema. Der letzte Beitrag () ist von sonne75.

    RegEx Verständnisproblem

    Hallo,

    ich versuche bei RegEx durchzusteigen, habe schon Tutorial hier gelesen, aber irgendwie fehlt mir noch was.

    Ich brauche einfach mehr Beispiele um es zu verstehen.

    Angenommen, ich habe einen String: "Wort1 Wort2 123 Wort3 456 Wort5 Wort6 34 Wort7 23 Wort8 76 Wort9". Ich möchte gerne alle Zahlen in ein Array, die sich zwischen "Wort5" und "Wort9" befinden. Wie würde der Ausdruck lauten?

    Danke schön.

    LG
    Warte, ich probier gerade mal ein bisschen rum.

    Edit @sonne75:
    Soooo, nach einigem Rumprobieren doch noch geschafft.

    VB.NET-Quellcode

    1. "(?<=(Wort5(.*)))((?<=( ))([0-9]*)(?=( )))(?=((.*)Wort9))"

    Da brauchst du nicht mal Gruppen zu verwenden, die Match-Collection enthält nur die gesuchten Zahlen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Artentus“ ()

    Verwende statt Regex.Match Regex.Matches, dann bekommst du eine MatchCollection zurück, die mehrere Matches enthält.

    Edit:
    Hier, eine schöne Zeile Code, die genau das macht, was du willst.

    VB.NET-Quellcode

    1. Dim numbers = Regex.Matches("Wort1 Wort2 123 Wort3 456 Wort5 Wort6 34 Wort7 23 Wort8 76 Wort9", "(?<=(Wort5(.*)))((?<=( ))([0-9]*)(?=( )))(?=((.*)Wort9))").OfType(Of Match).Select(Function(item) Integer.Parse(item.Value)).ToArray()

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()

    Ich habe es geschafft :) Ich habe erst sein Pattern benutzt, damit er den String beschneidet, auf "altroute-info"> <span>262 km</span>, <span>2 Stunden 33 Minuten". Und dann habe ich innerhalb dieses Strings mit Pattern "(\d+)" gesucht und habe eine MatchCollection mit diesen 3 Zahlen erhalten :thumbsup:

    EDIT: Und mit diesem Pattern:
    pattern = "( \d+)"

    habe ich aus meinem ursprünglichen String alle Zahlen (ohne die Zahlen am Ende von "Wort", deswegen Leerzeichen vor dem Slash) rausgeholt. Werde jetzt schauen, wie ich noch den Anfang und Ende begrenze.

    EDIT2: Hm, Begrenzung erscheint nicht so einfach. Nach seiner Methode funktioniert es komischerweise nicht...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „sonne75“ ()

    Wie du die Begrenzungen reinbringst habe ich dir doch schon gezeigt. Im Prinzip ist "(\d+)" nur ein Synonym für "([0-9]*)". Der Rest in meinem Pattern dient lediglich zur Begrenzung. Das sollte übrigens auch etwas zuverlässiger bei den Leerzeichen sein.
    Aber ich verstehe leider nicht, warum da so viele Klammern drum rum notwendig sind, könntest du mir den bitte auseinander nehmen und erklären, was wofür ist?
    Ich muss allerdins in 10 Minuten schon heim, kann erst morgen früh nachlesen.

    EDIT: also, ich sehe da mehrere Gruppen:
    1. (?<=(Wort5(.*))) - den Anfang begrenzen
    2. ((?<=( )) - um Leerzeichen zu entfernen?
    3. ([0-9]*) - das ist wohl das Gleiche wie (\d+)
    4. (?=( ))) - wieder Leerzeichen? Warum anders als bei 2.?
    5. (?=((.*)Wort9)) - das Ende begrenzen

    Was bewirken die Fragenzeichen mit und ohne "<"?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „sonne75“ ()

    Also der Teil in der Mitte ([0-9]+) sucht nach Zahlen (und ja, es müsste tatsächlich + und nicht * heißen, sorry). Das selbe macht auch \d+, weshalb du beide verwenden kannst.
    Der Rest sind sogenannte Lookaherd bzw. Lookbehinds. Diese suchen zwar nach einem Vorkommen des angegebenen Patterns, beziehen dieses aber nicht mit in den Match mit ein. Dies ist hier genau richtig, dann du willst ja nur Zahl an sich haben, der Rest ist nur ein Bedingung für die Zahl. Würde ich das ohne machen, so wäre immer noch alles von Wort5 bis Wort9 mit drin.
    Die Syntax eines Lookbehinds ist (?<=()), wobei in den inneren Klammern jeder beliebige Regex-Match stehen kann. Die Syntax für lookahed ist dementsprechend dann (?=()).
    Ich suche also eine Zahl, der ein Leerzeichen vorangeht und nachfolgt. Weiterhin muss irgendwo vor der Zahl "Wort5" vorkommen und irgendwo dahinter "Wort9".

    Edit:
    Ich hab übrigens gerade gemerkt, dass man da noch einiges optimieren kann.

    VB.NET-Quellcode

    1. "(?<=Wort5.* )\d+(?= .*Wort9)"