Ankündigung

Einklappen
Keine Ankündigung bisher.

Regulärer Ausdruck sucht nicht richtig

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Regulärer Ausdruck sucht nicht richtig

    Hallo zusammen,

    ich nutze einen regulären Ausdruck um einen String zu zerlegen.
    Zum Teil klappt das auch ganz gut, aber eben nur zum Teil.

    Hier der versuch der Funktioniert:
    PHP-Code:
    $string ='[FEEDBACK] Listing 3 Entrys:
               01 "Hallo" (1.3-t) by HSFighter
               06 <Failed> "Bin wieder da" (1.A.0) by mike, text by simom
               08 "was willst du" (1.2.2.0-acb) by Google.
    '
    ;

    $pluginpattern "/(?:\")(.*?)(?:\")(?: \()(.*?)(?:\))(?: by )(.*?)(?:\\n)/i";

    preg_match_all($pluginpattern$string$tarray); 
    Raus bekomme ich das hier:
    Code:
    Array
    (
        [0] => Array
            (
                [0] => "Hallo" (1.3) by HSFighter
                [1] => "Bin wieder da" (1.7.0) by mike, text by simom
                [2] => "was willst du" (1.2.0-acb) by Google.
            )
        [1] => Array
            (
                [0] => Hallo
                [1] => Bin wieder da
                [2] => was willst du
            )
        [2] => Array
            (
                [0] => 1.3
                [1] => 1.7.0
                [2] => 1.2.0-acb
            )
        [3] => Array
            (
                [0] => HSFighter
                [1] => mike, text by simom
                [2] => Google.
            )
    )
    Ab und zu steht aber auch mal ein <failed> im String. (siehe oben)
    Das möchte ich auch gerne mit extrahieren wenn es vorhanden ist.

    PHP-Code:
    $pluginpattern "/(?:\<)(.*?)(?:\>)(?:\")(.*?)(?:\")(?: \()(.*?)(?:\))(?: by )(.*?)(?:\\n)/i"
    Funktioniert leider nicht.

    Mal ganz abgesehen von der Zahl am Anfang der Zeile die auch noch mit in das Array muss!

    kann mir da jemand weiter helfen?

    MfG
    Wieso, weshalb, warum?
    Wer nicht fragt bleibt dumm!


  • #2
    Hallo,

    du musst das ganze etwas zerlegen, dann klappt es eigentlich meist. Ich weiß jetzt nicht so ganz was du wie parsen möchtest und warum <failed> ein Problem darstellt, aber siehs doch mal so:

    Zweistellige Zahl
    "<failed>" (optional)
    String in Anführungszeichen
    Version (?)
    "by"
    Autor

    Nun für jeden Token erstellst du einen RegExp und das ganze fügst du dann zu einem neuen RegExp zusammen:

    \d{2}
    (\<failed\>)?
    \".*\"
    \d+(\.\d)*(-\w+)?
    by
    .+

    Also (ungetestet)
    \d{2} (\<failed\> )?\".*\" \d+(\.\d)*(-\w+)? by .+

    Der Vorteil ist, du kannst relativ einfach debuggen und feststellen, welcher RegExp-Token fehlschlägt.
    "Mein Name ist Lohse, ich kaufe hier ein."

    Kommentar


    • #3
      Hi Critz,
      danke für deine schnelle Antwort.

      RegExp-Token alleine:

      \d{2} = Funktioniert
      \".*\" = Funktioniert auch
      Die Anderen leider nicht.

      ---
      Bin aber schon weiter gekommen.

      Digit am Anfang
      Text zwischen < und >
      Text zwischen " und "
      Text zwischen ( und )
      By überspringen
      Rest der Zeile bis Zeilenende (linebreak)

      $pluginpattern = "/(\\d+)(?: \<)(.*?)(?:\>)(?: \")(.*?)(?:\")(?: \()(.*?)(?:\))(?: by )(.*?)(?:\\n)/i";
      Ich gebe als Bedingung vor das diese Zeichenketten vorhanden sein sollen,
      da sonnst keine Auswertung der Zeile vergenommen werden darf.
      das Funktioniert auch Toll.

      Nur wertet er jetzt alle Zeilen aus de ein <failed> enthalten und die anderen nicht mehr.
      Das mit den <failed> muss aber optional sein.
      (\<failed\>)? funktioniert leider nicht.
      Wieso, weshalb, warum?
      Wer nicht fragt bleibt dumm!

      Kommentar


      • #4
        Hallo,
        also deine Konstrukte verstehe ich nicht, was sind das Lookbehind-Assertions? Ich wuerde noch U (ungreedy) als Modifier hinzufuegen und den Test auf failed wie von mir beschrieben einbauen. Vielleicht auch einfach in deinen alten Query, denn der funktioniert ja scheinbar bis auf <failed>. Mit (irgendwas)? machst du eine Gruppierung optional, was du ja suchst.
        "Mein Name ist Lohse, ich kaufe hier ein."

        Kommentar


        • #5
          ?: bewirkt, dass der gruppierte Ausdruck nicht einzeln im Ergebnis zur Verfügung steht, aber auch nicht mehr über einen Rückbezug angesprochen werden kann. Mir stellt sich allerdings auch die Frage, wozu du bestimmte Abschnitte in deinem Ausdruck überhaupt gruppierst.

          Das doppelte Escapen ist hier
          Code:
          (\\d+)
          irgendwie unnötig.

          Wie Chriz schon sagt, musst du diesen Teil
          Code:
          (?: \<)(.*?)(?:\>)
          als optional erklären und nicht
          Code:
          (\<failed\>)
          .

          Gruß
          http://hallophp.de

          Kommentar

          Lädt...
          X