Werner: inhalt zwischen 2 Wörtern auslesen (regex)

Hi Profies,

ich bin mal wieder am Verzweifeln mit regex
ich möchte den Text zwischen 2 Wörtern auslesen

$text= "sss: hallo ich bin der text ttt:";

if (preg_match_all("/sss:([ttt:]*)/", $text, $out))
{
echo $out[1];
}

Bekomme ich kein Ergebenis.
Wo liegt mein Gedankenfehler ?

Danke
Werner

  1. hi,

    $text= "sss: hallo ich bin der text ttt:";

    if (preg_match_all("/sss:([ttt:]*)/", $text, $out))

    Damit suchst du nach sss:, gefolgt von beliebig vielen Wiederholungen von Zeichen aus der Zeichenklasse [ttt:].

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. Hallo wahsaga.

      $text= "sss: hallo ich bin der text ttt:";

      if (preg_match_all("/sss:([ttt:]*)/", $text, $out))

      Damit suchst du nach sss:, gefolgt von beliebig vielen Wiederholungen von Zeichen aus der Zeichenklasse [ttt:].

      Wobei hiervon zwei „t“ überflüssig sind.

      Einen schönen Donnerstag noch.

      Gruß, Mathias

      --
      ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
      debian/rules
      1. Hallo wahsaga.

        $text= "sss: hallo ich bin der text ttt:";

        if (preg_match_all("/sss:([ttt:]*)/", $text, $out))

        Damit suchst du nach sss:, gefolgt von beliebig vielen Wiederholungen von Zeichen aus der Zeichenklasse [ttt:].

        Wobei hiervon zwei „t“ überflüssig sind.

        Einen schönen Donnerstag noch.

        Gruß, Mathias

        Danke,
        aber das bringt mir nicht die Erleuchtung :-(
        scheinbar stehe ich auf dem Schlauch.

        Wie wäre die richtige Syntax ?
        wenn ich den Inhalt zwischen sss: und ttt: auslesen will ?

        Werner

        1. Wie wäre die richtige Syntax ?
          wenn ich den Inhalt zwischen sss: und ttt: auslesen will ?

          /sss:(.*)(?=ttt:)/

          Das Gesuchte steht dann in $1.

          Siechfred

          --
          Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
          1. Wie wäre die richtige Syntax ?
            wenn ich den Inhalt zwischen sss: und ttt: auslesen will ?

            /sss:(.*)(?=ttt:)/

            Das Gesuchte steht dann in $1.

            Siechfred

            Hallo Siechfred,

            Ich komme einfach nicht vom Schlauch nicht runter :-(

            if (preg_match_all("/sss:([ttt:]*)/", $text, $out))
            {
            $text = $out[1];
            echo $text[0];
            }
            gibt kein Ergebenis

            kannst du mir bitte nochmal helfen ?
            Dankeschön
            Werner

            1. /sss:(.*)(?=ttt:)/
              Das Gesuchte steht dann in $1.
              Ich komme einfach nicht vom Schlauch nicht runter :-(

              Du solltest den Regulären Ausdruck auch so verwenden, wie ich dir vorschlug.

              Siechfred

              --
              Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
              1. /sss:(.*)(?=ttt:)/
                Das Gesuchte steht dann in $1.
                Ich komme einfach nicht vom Schlauch nicht runter :-(

                Du solltest den Regulären Ausdruck auch so verwenden, wie ich dir vorschlug.

                Siechfred

                hab doch bitte Gnade mit mir
                und poste den kompletten syntax

                bitte,bitte, ich blick das heute nicht
                Gruß Werner

                1. hi,

                  hab doch bitte Gnade mit mir
                  und poste den kompletten syntax

                  Du weisst, an welcher Stelle die Funktion einen regulären Ausdruck erwartet, und Siehfred hat dir einen seiner Meinung nach passenden genannt - also ist simples Einsetzen nur noch das, was du jetzt zu tun hast.

                  Und da preg_match_all ein Array mit den gefundenen Treffern zurückgibt, wäre es vielleicht auch ganz clever, sich dessen Struktur mal anzusehen - print_r/var_dump.

                  gruß,
                  wahsaga

                  --
                  /voodoo.css:
                  #GeorgeWBush { position:absolute; bottom:-6ft; }
                  1. hi,

                    hab doch bitte Gnade mit mir
                    und poste den kompletten syntax

                    Du weisst, an welcher Stelle die Funktion einen regulären Ausdruck erwartet, und Siehfred hat dir einen seiner Meinung nach passenden genannt - also ist simples Einsetzen nur noch das, was du jetzt zu tun hast.

                    Und da preg_match_all ein Array mit den gefundenen Treffern zurückgibt, wäre es vielleicht auch ganz clever, sich dessen Struktur mal anzusehen - print_r/var_dump.

                    gruß,
                    wahsaga

                    Hi,

                    das Problem liegt wo anderst

                    $text="sss:das ist der text ttt:";
                    if (preg_match_all("/sss:(.*)(?=ttt:)/", $text, $out))
                    {
                    #echo $out[1][0];
                    print_r ($out);
                    }
                    Funktioniert!
                    Array ( [0] => Array ( [0] => sss:das ist der text ) [1] => Array ( [0] => das ist der text ) )

                    Aber sobald ein Zeilenumbruch in $text ist
                    funktioniert es nicht mehr!

                    $text="sss:das ist der text mit
                    Umbruch ttt:";

                    if (preg_match_all("/sss:(.*)(?=ttt:)/", $text, $out))
                    {
                    #echo $out[1][0];
                    print_r ($out);
                    }
                    keine Ausgabe mit PHP Version 5.0.3
                    Liegt es an der PHP Version ?

                    Werner

                    1. das Problem liegt wo anderst
                      [...]
                      Aber sobald ein Zeilenumbruch in $text ist
                      funktioniert es nicht mehr!

                      Dann verwende den s-Modifier (siehe Suchmuster-Modifikatoren).

                      Siechfred

                      --
                      Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
                      1. das Problem liegt wo anderst
                        [...]
                        Aber sobald ein Zeilenumbruch in $text ist
                        funktioniert es nicht mehr!

                        Dann verwende den s-Modifier (siehe Suchmuster-Modifikatoren).

                        Siechfred

                        Danke Siechfried,

                        ich finde es immer wieder gut das php.net zwar erklärt was
                        z.B. Modifikatoren machen, aber ohne Beispiel
                        wo der Modifikator eingebunden werden muß

                        Ich denke so ?

                        (preg_match_all("/sss:(.*)(?=ttt:)]/s", $text, $out))

                        Wenn ja, war das nicht die Lösung

                        Danke
                        Werner

                        1. Hallo Werner.

                          das Problem liegt wo anderst
                          [...]
                          Aber sobald ein Zeilenumbruch in $text ist
                          funktioniert es nicht mehr!

                          Dann verwende den s-Modifier (siehe Suchmuster-Modifikatoren).

                          ich finde es immer wieder gut das php.net zwar erklärt was
                          z.B. Modifikatoren machen, aber ohne Beispiel
                          wo der Modifikator eingebunden werden muß

                          Du darfst durchaus die Nutzerkommentare darunter lesen …

                          Einen schönen Donnerstag noch.

                          Gruß, Mathias

                          --
                          ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
                          debian/rules
                        2. ich finde es immer wieder gut das php.net zwar erklärt was
                          z.B. Modifikatoren machen, aber ohne Beispiel
                          wo der Modifikator eingebunden werden muß

                          Ich nahm an, dass dir die PCRE-Syntax vertraut ist, schließlich hattest du ja bereits einen Regulären Ausdruck in Gebrauch.

                          (preg_match_all("/sss:(.*)(?=ttt:)]/s", $text, $out))
                          Wenn ja, war das nicht die Lösung

                          Doch, genau das ist die Lösung, wenn du noch die Artefakte deines ersten Versuchs beseitigst (ich meine diese einsame eckige Klammer ziemlich am Ende deines Regulären Ausdrucks, die da nicht mehr hingehört).

                          Siechfred

                          --
                          Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
          2. Hallo Siechfred!

            /sss:(.*)(?=ttt:)/

            Funktionieren PHP-RegExps anders?
            In Perl erhalte ich: »das ist der text ttt:«.

              
            my $text = my $such = "sss:das ist der text ttt:";  
            $such =~ s/sss:(.*)(?=ttt:)/$1/;  
            print $such; # Ausgabe: das ist der text ttt:  
            
            

            Zu dem empfohlenen Modifier »s«. Ist es nicht so, dass »s« lediglich bewirkt, dass ».« auch auf Newline-Zeichen matcht (ohne »s« halt nicht). Warum nicht den Modifier »m« in dem Fall?

            Viele Grüße aus Frankfurt/Main,
            Patrick

            --

            _ - jenseits vom delirium - _
            [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
            Nichts ist unmöglich? Doch!
            Heute schon gegökt?
            1. /sss:(.*)(?=ttt:)/
              Funktionieren PHP-RegExps anders?

              M.E. nicht, wenn du die Perl-kompatible Syntax verwendest (PCRE).

              In Perl erhalte ich: »das ist der text ttt:«.

              my $text = my $such = "sss:das ist der text ttt:";
              $such =~ s/sss:(.*)(?=ttt:)/$1/;
              print $such; # Ausgabe: das ist der text ttt:

                
              Schau doch mal, was dein Code macht. Er sucht innerhalb des Ausgangsstrings nach dem vorgegebenen Muster und ersetzt es durch das, was geklammert wurde. Die Besonderheit ist jetzt, dass (?=ttt:) eine nicht-gruppierende Klammer ist, das Ergebnis also nicht in den RegExp einbezogen wird. Der Ausdruck lautet nämlich: Finde ein 'sss:' und alles, was folgt, bis du auf 'ttt:' stößt, was bedeutet, dass das Lookahead-Konstrukt nicht Bestandteil des zu suchenden und ersetzenden Stringteils ist. Mache mal Folgendes:  
                
              ~~~perl
              my $text= "sss: hallo ich bin der text ttt:";  
              $text =~ s/sss:(.*)(?=ttt:)/>$1</;  
              print $text;
              

              Das dürfte die Erleuchtung sein :)

              Zu dem empfohlenen Modifier »s«. Ist es nicht so, dass »s« lediglich bewirkt, dass ».« auch auf Newline-Zeichen matcht (ohne »s« halt nicht). Warum nicht den Modifier »m« in dem Fall?

              Weil //m bedeutet, dass die Zeichenklasse '.' auf alles *außer* Newlines matcht, während //s die Newlines einschließt.

              Siechfred

              --
              Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
              1. Hallo Siechfred!

                my $text= "sss: hallo ich bin der text ttt:";

                $text =~ s/sss:(.*)(?=ttt:)/>$1</;
                print $text;

                
                > Das dürfte die Erleuchtung sein :)  
                  
                Hm, ja :) Ich sehe jetzt, dass $1 jetzt den Inhalt des ersten Klammerpaares ist, aber das ist auch das, was ich erwartete. Nur die Funktionsweise des Lookaheads will mir nicht so recht ins Head ;)  
                  
                  
                
                > bedeutet, dass das Lookahead-Konstrukt nicht Bestandteil des zu suchenden und ersetzenden Stringteils ist.  
                  
                ... und wurde deswegen bei meinem Beispiel mit ausgegeben? Wozu ist dann so etwas gut, wollte der OP nicht $1 extrahieren?  
                  
                
                > Weil //m bedeutet, dass die Zeichenklasse '.' auf alles \*außer\* Newlines matcht, während //s die Newlines einschließt.  
                  
                Erlaubt nicht »m« das Suchen über mehrere Zeilen hinweg, in dem es den zu durchsuchenden Text betrachtet, als wäre es -sozusagen- eine Zeile?  
                  
                Viele Grüße aus Frankfurt/Main,  
                Patrick
                
                -- 
                ![](http://www.atomic-eggs.com/clubsig.gif)  
                  
                \_ - jenseits vom delirium - \_  
                  
                [[link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash](http://www.atomic-eggs.com/)]  
                Nichts ist unmöglich? [Doch!](http://www.atomic-eggs.com/cwi/cwi_4.shtml)  
                Heute schon ge[gök](http://goek.atomic-eggs.com/goek_goek.html)t?
                
                1. Hm, ja :) Ich sehe jetzt, dass $1 jetzt den Inhalt des ersten Klammerpaares ist, aber das ist auch das, was ich erwartete. Nur die Funktionsweise des Lookaheads will mir nicht so recht ins Head ;)

                  Grundwissen zum Verständnis: Die Klammer um Lookaround-Konstrukte dient *nicht* der Gruppierung in Teilausdrücke. Mein Beispiel mal etwas abgewandelt:

                  my $text = 'foo:bar:baz:bum:foo';  
                  $text =~ /(?<=foo:)(.*)(?=:foo)/;
                  

                  Jetzt scheint dein erster Denkfehler zu sein, dass $1 das Lookbehind, $3 das Lookahead und $2 alles dazwischen enthält, doch dem ist nicht so. Es gibt nur einen geklammerten Teilausdruck, und das ist in $1 alles zwischen 'foo'. Die Lookarounds dagegen sind 'zero-width assertions'.

                  bedeutet, dass das Lookahead-Konstrukt nicht Bestandteil des zu suchenden und ersetzenden Stringteils ist.
                  ... und wurde deswegen bei meinem Beispiel mit ausgegeben? Wozu ist dann so etwas gut, wollte der OP nicht $1 extrahieren?

                  Das bekommt er auch, indem er $1 abfragt. Um mal mein Beispiel auseinanderzunehmen:

                  (?<=foo:)(.*)(?=:foo) = Finde alles, was zwischen 'foo:' und ':foo' steht. Ergebnis: 'bar:baz:bum'. Das sollte dir einleuchten :)

                  Jetzt zurück zu deiner Ersetzung:

                  $text = s/(?<=foo:)(.*)(?=:foo)/$1/s;

                  Der String lautete 'foo:bar:baz:bum:foo', was der RegExp bedeutet, habe ich geschrieben. Im Ergebnis passt also vom Ausgangsstring der Teilstring 'bar:baz:bum' auf den RegExp. Dieser Teil wird zugleich in $1 geklammert. Wenn du dir jetzt dein Beispiel ansiehst, wirst du sehen, dass deine Ersetzung keine echte[tm] ist, denn der Teilstring, der auf das Muster passt, ist identisch mit dem Teilstring, den du in $1 gespeichert hast. Ergo wird oben stehende Anweisung im Ergebnis nichts am Ausgangsstring verändern, da 'bar:baz:bum' durch 'bar:baz:bum' ersetzt wird. Suchen- und Ersetzen ist eben nicht zum Extrahieren von Teilstrings geeignet, deinen Ansatz würde ich durch

                  $text =~ s/(foo:|:foo)//gs;

                  lösen.

                  Weil //m bedeutet, dass die Zeichenklasse '.' auf alles *außer* Newlines matcht, während //s die Newlines einschließt.
                  Erlaubt nicht »m« das Suchen über mehrere Zeilen hinweg, in dem es den zu durchsuchenden Text betrachtet, als wäre es -sozusagen- eine Zeile?

                  Nein, das tut jeder RegExp, so lange die mehreren Zeilen in einem Skalar durch Newlines getrennt vorliegen. Die besondere Bedeutung liegt neben der Zeichenklasse '.' im Verhalten der Anker '^' und '$'. Bei //s sind dies Stringanfang und -ende, bei //m sind dies Zeilenanfang- und Ende. Beispiele mit Erläuterung dazu findest du in perlretut (musst ein bisschen nach unten scrollen).

                  Siechfred

                  --
                  Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
                  1. Hallo Siechfred!

                    Grundwissen zum Verständnis: Die Klammer um Lookaround-Konstrukte dient *nicht* der Gruppierung in Teilausdrücke.

                    Soweit war mir das bekannt.

                    my $text = 'foo:bar:baz:bum:foo';

                    $text =~ /(?<=foo:)(.*)(?=:foo)/;

                    
                    > Jetzt scheint dein erster Denkfehler zu sein, dass $1 das Lookbehind, $3 das Lookahead und $2 alles dazwischen enthält  
                      
                    Nein, ich wüßte bei diesem neuen Beispiel schon, dass $1 der Inhalt des zweitem Klammerpaars ist.  
                      
                    Aber das:  
                      
                    
                    > dass deine Ersetzung keine echte[tm] ist, denn der Teilstring, der auf das Muster passt, ist identisch mit dem Teilstring, den du in $1 gespeichert hast. Ergo wird oben stehende Anweisung im Ergebnis nichts am Ausgangsstring verändern, da 'bar:baz:bum' durch 'bar:baz:bum' ersetzt wird.  
                      
                    war mit nicht ganz klar. Jetzt denke ich schon. Danke!  
                      
                      
                    Zu /m und /s: Ich hatte vor langer Zeit meine liebe Not, aus  HTML-Dateien alles zwischen <form action="..." ......> und </form> (inklusive der Tags) zu entfernen. Das komplette, zu entfernende Formular erstreckte sich über mehrere Zeilen, deren Anzahl  
                     nicht bekannt war, weil sie von Datei zu Datei variierte. Irgendwann habe ich die HTML-Dateien dann in Einzeilern umgewandelt, da gings (und logischerweise ohne die Modifier, da jede Datei nur noch ein einzeiliger String war)!  
                      
                    Viele Grüße aus Frankfurt/Main,  
                    Patrick
                    
                    -- 
                    ![](http://www.atomic-eggs.com/clubsig.gif)  
                      
                    \_ - jenseits vom delirium - \_  
                      
                    [[link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash](http://www.atomic-eggs.com/)]  
                    Nichts ist unmöglich? [Doch!](http://www.atomic-eggs.com/cwi/cwi_4.shtml)  
                    Heute schon ge[gök](http://goek.atomic-eggs.com/goek_goek.html)t?