inhalt zwischen 2 Wörtern auslesen (regex)
Werner
- php
0 wahsaga0 Mathias Brodala0 Werner0 Siechfred
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
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
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
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
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
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
/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
/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
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,
hab doch bitte Gnade mit mir
und poste den kompletten syntaxDu 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
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
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
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
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
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
/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
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?
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
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?