Ankündigung

Einklappen
Keine Ankündigung bisher.

RegExp: Negierte Back References?

Einklappen

Neue Werbung 2019

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

  • RegExp: Negierte Back References?

    Tja, mal wieder treiben mich reguläre Ausdrücke zum Wahnsinn.

    Ich will einen regulären Ausdrück für folgendes. Ich habe z.B. eine Zeile ähnlich einer Variablenzuweisung in PHP, sowas wie
    muh = "eek";
    Was ich jetzt möchte ist eek auslesen. Das an sich ist nicht so schwer. Problematisch wird es dann aber wenn folgendes dazu kommt:
    1) eek kann auch ein mehrzeiliger Text sein (newlines sind keine Begrenzungen)
    2) " können auch durch ' ersetzt werden
    3) Nach der Zeile können noch ähnliche Zeilen auftauchen, ich muss also aufpassen das nicht zuviel gematcht wird

    So ... ich hatte es jetzt probiert mit folgendem Regexp:
    /^[a-z0-9\._-]+ *= *("|\')[^\1]+\1 *;/ims

    Um euch das lesen etwas zu vereinfachen:
    ^[a-z0-9\._-]+: Am Anfang des Strings kommt der "Variablenname" der nur aus den angegeben zeichen bestehen darf
    Danach kommen beliebig viele Whitespaces
    Dann ein =
    Dann wieder beliebige Whitespaces
    Dann entweder ein " oder '
    Jetzt soll jedes beliebige Zeichen kommen außer " oder ', je nachdem was gematcht wurde
    Dann ein " oder ', je nachdem was gematcht wurde
    Wieder mal beliebig viele Whitespaces
    Schließlich ein ;

    So, das Problem: Diese "Back References", also das \1, funktionieren nicht in eckigen Klammern.

    Lange Rede kurzer Sinn: Gibt es dafür ein Workaround oder hat jemand evtl. sogar einen besseren Ansatz für mein Problem? Das Problem ist ganz einfach das ich verbieten muss das " oder ' (je nachdem was eben eingesetzt wird um die Zeichenkette zu begrenzen) in der Zeichenkette vorkommen, da ich sonst schwachsinnige Ergebnisse kriege.
    der U-Modifier ist leider auch keine Lösung, da ich später noch escaping einbauen will. Und bei U würde sowas wie
    muh = "ee\"k";
    nur bis vor das k gematcht werden.

    Naja: Ideen?

    Danke
    BlackWolf

  • #2
    So, das Problem: Diese "Back References", also das \1, funktionieren nicht in eckigen Klammern.
    Du musst IMHO "\\1" schreiben, sonst wird der Backslash nicht erkannt...?
    Viele Grüße,
    Dr.E.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1. Think about software design [B]before[/B] you start to write code!
    2. Discuss and review it together with [B]experts[/B]!
    3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
    4. Write [I][B]clean and reusable[/B][/I] software only!
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Kommentar


    • #3
      Zitat von dr.e. Beitrag anzeigen
      Du musst IMHO "\\1" schreiben, sonst wird der Backslash nicht erkannt...?
      Nein, weil das Backslash in dem Fall Teil der Syntax ist.
      Die Back-Reference funktioniert auch über \1, nur eben nicht in den eckigen Klammern, was aber eben auch das PHP-Manual sagt. Das gibt es nicht.

      Die Frage ist wie ich mein Problem gelöst kriege.

      Kommentar


      • #4
        Hi,

        dann versuche nochmal statt "\1" ein "$1" zu schreiben. Bei mir tut folgender Code seinen Dienst:

        PHP-Code:
        $test 'fo9o="b
           a
           mein )=(/&%$/()=Itest
           r";'
        ;
        preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}\"([^\"]+)\";/iUms',$test,$matches);
        echo 
        print_r($matches); 
        Viele Grüße,
        Dr.E.

        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        1. Think about software design [B]before[/B] you start to write code!
        2. Discuss and review it together with [B]experts[/B]!
        3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
        4. Write [I][B]clean and reusable[/B][/I] software only!
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        Kommentar


        • #5
          Zitat von dr.e. Beitrag anzeigen
          Hi,

          dann versuche nochmal statt "\1" ein "$1" zu schreiben. Bei mir tut folgender Code seinen Dienst:

          PHP-Code:
          $test 'fo9o="b
             a
             mein )=(/&%$/()=Itest
             r";'
          ;
          preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}\"([^\"]+)\";/iUms',$test,$matches);
          echo 
          print_r($matches); 
          ne, $1 hatte ich auch schon probiert, tuts leider nich.
          Dein Code wäre mein Ausweich-Code gewesen, dann muss die rechte Seite vom Gleichheitszeichen halt in " eingeschlossen sein, ' sind dann tabu.
          Ich hätte es halt gerne habt das ich sowohl " als auch ' verwenden kann, aber das scheint nicht möglich zu sein.

          Danke auf jeden Fall!

          mfg

          Kommentar


          • #6
            Ich hätte es halt gerne habt das ich sowohl " als auch ' verwenden kann, aber das scheint nicht möglich zu sein.
            Das Problem dabei ist das ODER. Es gibt demnach keine Zusage darüber, dass, falls beim ersten Versuch ein " verwendet wurde, dies auch beim zweiten Mal erfolgt. Man muss sich entweder entscheiden oder auf strpos() & substr() umsteigen. Regexps geben das in dieser Form nicht her.

            Danke auf jeden Fall!
            Gerne.
            Viele Grüße,
            Dr.E.

            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            1. Think about software design [B]before[/B] you start to write code!
            2. Discuss and review it together with [B]experts[/B]!
            3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
            4. Write [I][B]clean and reusable[/B][/I] software only!
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            Kommentar


            • #7
              Hmm, na wozu brauchst Du denn Klassen:

              Code:
              preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}([\"\'])(.+)\2;/iUms',$test,$matches);
              oder ähnlich (ungetestet) sollte mit ungreedy doch auch gehen.
              Zudem kannst Du auch beide Fälle als oder darstellen:
              Code:
              ...(?:\"([^\"]+)\"|\'([^\']+)\')...
              [COLOR="#F5F5FF"]--[/COLOR]
              [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
              „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
              [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
              [COLOR="#F5F5FF"]
              --[/COLOR]

              Kommentar


              • #8
                Zitat von dr.e. Beitrag anzeigen
                Das Problem dabei ist das ODER. Es gibt demnach keine Zusage darüber, dass, falls beim ersten Versuch ein " verwendet wurde, dies auch beim zweiten Mal erfolgt. Man muss sich entweder entscheiden oder auf strpos() & substr() umsteigen. Regexps geben das in dieser Form nicht her.


                Gerne.
                Naja, geben sie in dem Sinne schon, nämlich eben über Back References. Aber Back References lassen sich eben nicht in Verbindung mit NOT verwenden, das ist das Problem. Sowas z.B. geht aber schon:
                ("|')(.+)\1
                das würde "muh" und 'muh' matchen, aber nicht "muh'
                Das aber nur so am Rande ...

                Aber werde dann wohl einfach festlegen das " verwendet werden müssen.

                Wenn ich das Topic aber schon grad offen hab nämlich noch ne kleine Frage: Hat jemand ne Idee wie ich ein escape zeichen einbaun kann? Im Klartext:
                "ha"llo"
                soll nicht gematcht werden aber
                "ha\"llo"
                eben schon.

                Ich hatte es versucht mit
                [^[^\\]"]+
                das wollte aber nicht.

                Kommentar


                • #9
                  PHP-Code:
                  $test ="sdjklfhd = 'abcd\"';";

                  preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}([\"\'])(.+)\2;/iUms',$test,$matches);
                  print_r($matches);

                  $test ='sdjklfhd = "abcd\'sadsa";';

                  preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}([\"\'])(.+)\2;/iUms',$test,$matches);
                  print_r($matches);
                  /*
                  Array
                  (
                      [0] => sdjklfhd = 'abcd"';
                      [1] => sdjklfhd
                      [2] => '
                      [3] => abcd"
                  )
                  Array
                  (
                      [0] => sdjklfhd = "abcd'sadsa";
                      [1] => sdjklfhd
                      [2] => "
                      [3] => abcd'sadsa
                  )

                  */ 
                  Man kann sogar escapte Delimiter eibauen mit einem Oder Statement.
                  [COLOR="#F5F5FF"]--[/COLOR]
                  [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
                  „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                  [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
                  [COLOR="#F5F5FF"]
                  --[/COLOR]

                  Kommentar


                  • #10
                    Das aber nur so am Rande ...
                    Danke für den Hinweis, man lernt nie aus.
                    Viele Grüße,
                    Dr.E.

                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    1. Think about software design [B]before[/B] you start to write code!
                    2. Discuss and review it together with [B]experts[/B]!
                    3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
                    4. Write [I][B]clean and reusable[/B][/I] software only!
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                    Kommentar


                    • #11
                      Escapezeichen gehen über ODER und Wiederholung:

                      *kram* irgendwo hatte ich das schon mal umgesetzt: muß ich nachliefern...

                      [edit]
                      Nur mal exemplarisch für die DblQuotes:
                      Code:
                      preg_match_all ('#\"((?:(?:\\\")|[^\\"]+)+)\"#U' , $test , $aElements);
                      Mit escapten backslashes wirds wieder ein Stück komplizierter.
                      [COLOR="#F5F5FF"]--[/COLOR]
                      [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
                      „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                      [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
                      [COLOR="#F5F5FF"]
                      --[/COLOR]

                      Kommentar

                      Lädt...
                      X