RegExp - mehrere Stellen in einem String sollen gefunden werden

  • Hallo,

    ich habe folgendes Problem:

    Ich möchte, dass RegExp mehrere Textstellen findet, die zwischen klar definierten Tags stehen, also:

    <Stelle1> Erster Text </Stelle1>

    blbabla blubb.... unterschiedlich lang mit Zeilenumbrüchen

    <Stelle2> Zweiter Text </Stelle2>

    Bisher habe ich folgendes dazu hinbekommen:

    Code
    (?s)<Stelle1>(.*)</Stelle1>.*?<Stelle2>(.*)</Stelle2>

    Der Regex-Coach findet das auch ganz nett, aber wenn ich das im Auoti-Script einbaue, bringt er mir als Wert eine 1 zurück, also ungütige Expression.

    Das liegt wohl daran, dass meine Suchanfrage mehfrach gefunden werden soll. Einfach funktioniert sie.

    Wie müsste das richtig lauten?

    Danke für die Hilfe und viele Grüße

    André

    2 Mal editiert, zuletzt von Andre_ (6. Mai 2012 um 19:55) aus folgendem Grund: closed

  • nein, die 1 bedeutet, dass das Pattern gematched wurde.
    Schau dir die Flags an, 3 als Flag gibts dir beispielsweise ein Array zurück mit den Ergebnissen, also das was du haben willst.

    mfg K4z

  • Zitat

    Das liegt leider, am ".":
    "Normally matches any character except a newline. "
    Aber da findest du sicher selber ein Weg dran vorbei:)


    Was?...

    Zitat von Hilfe

    (?s) . matches anything including newline. (by default "." don't match newline)


    Ich hab ihm bei dem Pattern in der SB geholfen, und ihm das mit dem (?s) switch schon gesagt ;).

    @Andre Kannst du mal zeigen, welches Pattern du genau wie verwendet hast? Am besten den Ausschnitt im Quellcode. Vielleicht auch gleich noch ein Beispiel, dann wissen wir wie das Pattern ungefähr aussehen muss.

  • Ok, hier die Infos:

    Zunächst die Regexp-Zeile, die ich bis jetzt gebastelt habe:

    [autoit]

    $regexp_test = StringRegExp($database,'(?s)<Item Class="Feld_1" ID="{(.*)}">.*?<Unterfeld_1>(.*)</Unterfeld_1>.*?<Unterfeld_2>(.*)</Unterfeld_2>.*?<Unterfeld_5>(.*)</Unterfeld_5>',3)

    [/autoit]

    Ein Teil aus der $database wäre sowas hier:

    Einmal editiert, zuletzt von Andre_ (27. März 2012 um 08:17)

  • So vielleicht? Es liefert mir zwar momentan das von dir gewünschte Ergebnis, aber eine Garantie auf Richtigkeit gibt es von mir nicht dazu :D ...
    Was meinen die Experten?

    [autoit]

    $regexp_test = StringRegExp($database,'(?s)<Item Class="Feld_1" ID="{(.*?)}">.*?<Unterfeld_1>(.*?)</Unterfeld_1>.*?<Unterfeld_2>(.*?)</Unterfeld_2>.*?<Unterfeld_5>(.*?)</Unterfeld_5>',3)

    [/autoit]

    Gruß
    Trainer

    2 Mal editiert, zuletzt von ip_trainer (27. März 2012 um 09:08)

  • ip_trainer:

    Das funktioniert für genau diese Zeile. Aber: Es funktioniert nicht generell (habe noch ein paar andere Abfragen, die mit dieser Syntax kein sauberes Ergebnis liefern).

    i2c:

    Ich verstehe die Anwendung des _XMLDomWrappers leider überhaupt nicht. Gibt es irgendwo eine kurze Dokumentation bzw. Beispiele mit Erklärungen?

    Prinzipiell bin ich ja mit der RegExp schon relativ weit, aber sie funktioniert halt noch nicht überall zuverlässig.


    Hat jemand vielleicht noch eine Idee, was an der Zeile vom ip_trainer nicht stimmen könnte?

  • Ich möchte die Felder bzw. Unterfelder in der Expression immer frei bestimmen können, d.h. mal habe ich Feld 1 und Unterfeld 1,2,5. Es kann aber sein, dass zwischen Unterfeld 1 und 2 irgendwann ein weiteres Feld sich einträgt. Es kann auch sein, dass ich die Unterfelder 4,6 und 8 haben möchte.

    <Das Feld will ich haben> Genau das hier </Das Feld will ich haben>

    es folgend mehrere Zeilen mit unterschieldichsten Inhalten

    <Das feld will ich auch haben> Eben diesen Wert >/Das Feld will ich auch haben>

    Im Array sollten dann stehen:

    [0] Genau das hier

    [1] Eben diesen Wert

  • Wenn sich das gesuchte Feld öfters ändern, dann musst du das Pattern mit Hilfe von Variablen flexibler gestalten.
    Zum Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sTest = "<AutoIt>1243287</Autoit>" & @CRLF & "<Andre>83847</Andre>" & @CRLF & "<Test>65312</Test>" & @CRLF & "<foo>444</foo>" & @CRLF & "<1337>34535</1337>" ;HTML String

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aSearch[3] = ["AutoIt", "Test", "1337"] ;Suchbegriffe
    Dim $aResult[1] = [0] ;Ergebnis Array
    For $i = 0 To UBound($aSearch) - 1
    $sTemp = StringRegExpReplace($sTest, "(?i)(?s).*<" & $aSearch[$i] & ">(.+?)</" & $aSearch[$i] & ">.*", "$1")
    If Not @error Then
    $aResult[0] += 1
    ReDim $aResult[$aResult[0] + 1]
    $aResult[$aResult[0]] = $sTemp
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _ArrayDisplay($aResult)

    [/autoit]

    Aber ich denke, da ist i2cs Vorschlag wesentlich besser.

  • Dein Beispiel ist super.

    Aber bei einer Sache hatte ich mich vielleicht undeutlich ausgedrückt: Die erste Stelle, die gesucht wird, hat die Syntax:

    <Item Class="Feld_1" ID="{ZU FINDENDER WERT}">

    Erst danch kommen die Unterfelder mit

    <Unterfeld_1>ZU FINDENDER WERT </Unterfeld_1>

    zwischendrinn steht irgendwas

    <Unterfeld_2>ZU FINDENDER WERT </Unterfeld_2>

    Wenn ich Dein Beispiel richtig verstehe, findet er mir nur die Unterfelder, aber nicht die passende ItemClass ganz am Anfang.

    Geht bei der Zeile von IP_Trainer denn nichts in der Richtung bzw. was stimmt hier noch nicht??

    [autoit]


    $regexp_test = StringRegExp($database,'(?s)<Item Class="Feld_1" ID="{(.*?)}">.*?<Unterfeld_1>(.*?)</Unterfeld_1>.*?<Unterfeld_2>(.*?)</Unterfeld_2>.*?<Unterfeld_5>(.*?)</Unterfeld_5>',3)

    [/autoit]

    Die gesuchten Felder sind zwar ein paarmal anders, aber dafür bräucht es nicht unbedingt eine Flexibilisierung. Da es oft auch mehrere Unterfelder sind, die in einem Array abgelegt werden sollen, würde ich die entsprechenden Suchabfragen jeweils individuell gestalten.

  • Die Zeile würde alle passenden Unterfelder finden. Auch in Feld 2 oder 3 etc..
    Probier mal das hier:

    [autoit]

    $regexp_test = StringRegExp($database,'(?s)<Item Class="Feld_1" ID="{(.*?)}">.*?<Unterfeld_1>(.*?)</Unterfeld_1>.*?<Unterfeld_2>(.*?)</Unterfeld_2>.*?<Unterfeld_5>(.*?)</Unterfeld_5>.*?</Item>',3)

    [/autoit]