Archiv verlassen und diese Seite im Standarddesign anzeigen : probleme mit regex
hi all
ich hab mit php eine quellcode eingelesen und nun möchte ich divers tags entfernen
$suche=array('/<font.*>/');
$string2 = preg_replace($suche,"",$string);
da wird mit ganz geschmeidig auch text weggehauen, der nach dem font tag kommt.
kann mir jemand einen tipp geben?
thx cu SHB
Jep, Regex arbeitet per Definition "greedy" (gierig). Das heißt es versucht soviel wie möglich zur erschlagen. Zum Beispiel
Ich weiß, dies ist kein XHTML konformer HTML-Code.
<font size="1"><b>Mein Text</b></font>Wenn Du hierauf ein Regex-Match nach
/<font.*>/Sucht Regex nach dem ersten Vorkommen von "<font" und dem letzten vorkommen von ">". Dies wäre im obigen Beispiel praktisch alles. Du hast jetzt zwei Möglichkeiten. Entweder weist Du Regex an "ungreedy" zu arbeiten (siehe Doku (http://de3.php.net/manual/de/reference.pcre.pattern.modifiers.php)):
/<font.*>/U
Eine andere Möglichkeit wäre: Du weißt, daß innerhalb des Tags kein End-Tag auftreten darf. Also nimmst Du einen entsprechenden Ausschluß vor; alles außer:
/<font[^>]*>/
Allerdings hat dies die Gefahr, daß bei manchen Tags innerhalb der Anführungszeichen das "End-Tag" vorkommen darf:
<img src="bild.jpg" alt="das ist ein End-Tag: >"> Dann wird es schwierig. Deswegen sind die Regex manchmal eine Wissenschaft für sich.
Pingu
undefined
29-10-2005, 12:02
PHP Manual
strip_tags() ;)
michael.sprick
29-10-2005, 12:37
Hey Pingu,
das mit dem greedy ist hier nicht ganz richtig...
Der Modifier 'g' bewirkt, dass das Muster nach dem ersten match noch weiter gesucht wird...Also alle Vorkommen von $Pattern gefunden werden:
s/abc/def/; # ersetzt einmalig 'abc' gegen 'def' und bricht dann ab
s/abc/def/g; #ersetzt alle 'abc' gegen 'def'
Das bedeutet greedy.
In dem Fall von shb passiert aber etwas anderes. Hier stimmt nämlich das Pattern einfach nicht.
$suche=array('/<font.*>/');
Der '.' passt auf jedes beliebige Zeichen - auch '>' und der Stern steht für 0-n.
Das heißt dann also, dass alles was zwischen
<font und > steht, passt.
Von diesem String bleibt also nix mehr übrig
$var = "<font size=\"2\">Hallo Welt<br /><i>Noch mehr Text</i>";
Von diesem hier noch das 'asdf' am Ende
$var = "<font size=\"2\">Hallo Welt<br /><i>Noch mehr Text</i>asdf";
Eine Möglichkeit zur Lösung des Problems hast Du bereits genannt - eine andere wäre, mit dem '?' das matching auf ein Minimum zu beschränken:
$suche = array('/<font.*?>/');
Das nur nebenbei, damit es keine Mißverständnisse wegen 'greedy' gibt ;)
Gruß, Michael
Eine Möglichkeit zur Lösung des Problems hast Du bereits genannt - eine andere wäre, mit dem '?' das matching auf ein Minimum zu beschränken:
$suche = array('/<font.*?>/');
Das nur nebenbei, damit es keine Mißverständnisse wegen 'greedy' gibt ;)
http://de3.php.net/manual/de/reference.pcre.pattern.syntax.php#regexp.reference .internal-options
By default, the quantifiers are "greedy", that is, they match as much as possible (up to the maximum number of permitted times), without causing the rest of the pattern to fail. The classic example of where this gives problems is in trying to match comments in C programs. These appear between the sequences /* and */ and within the sequence, individual * and / characters may appear. An attempt to match C comments by applying the pattern /\*.*\*/ to the string /* first command */ not comment /* second comment */ fails, because it matches the entire string due to the greediness of the .* item.
However, if a quantifier is followed by a question mark, then it ceases to be greedy, and instead matches the minimum number of times possible, so the pattern /\*.*?\*/ does the right thing with the C comments. The meaning of the various quantifiers is not otherwise changed, just the preferred number of matches. Do not confuse this use of question mark with its use as a quantifier in its own right. Because it has two uses, it can sometimes appear doubled, as in \d??\d which matches one digit by preference, but can match two if that is the only way the rest of the pattern matches.
http://de3.php.net/manual/de/reference.pcre.pattern.modifiers.php
U (PCRE_UNGREEDY)
Dieser Modifikator kehrt die Gier von Quantifikatoren um, sodass sie standardmäßig nicht gierig sind, aber gierig werden, wenn ihnen ein "?" folgt. Das ist nicht mit Perl kompatibel. Es kann auch innerhalb des Suchmusters mit dem Modifikator (?U) oder durch ein Fragezeichen hinter dem Quantifikator (z.B. .*?) gesetzt werden.
Soviel zu greedy und ungreedy ;).
Pingu
michael.sprick
29-10-2005, 15:04
ah - OK... dann hat PHP da wieder gewisse Eigenarten...
By default, the quantifiers are "greedy", that is, they match as much as possibleSchon dem ersten Satz kann ich nämlich eigentlich nicht ganz zustimmen. Aber das mag daran liegen, dass ich Perl programmiere - nicht PHP.
In Perl ist dieser Ausdruck nicht gierig... löscht also nur das erste Vorkommen von <font size="2">
$var =~ s/<font.*?>//;
Dieser hingegen löscht alle Vorkommen von <font size="2">
$var =~ s/<font.*?>//g;
...und wird damit gierig (obwohl der Quantifier durch das ? eingescchränkt ist)
In Perl sind Quantifier und Modifier also zwei völlig unterschiedliche Dinge während sie in PHP scheinbar ineinanderfließen...
OK - dann sorry - ich wollte keine Verwirrung stiften ;)
super danke es hat geklappt ich hab es mit /U gemacht.
thx cu SHB
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.