[PHP] Regulärer Ausdruck
-
Hi,
ich brauche einen regulären Ausdruck für folgendes Problem:
Ich habe einen String, in dem Tags stehen, die so aussehen: [_a], [_b], etc. und [/_a], [/_b].
Zwischen den Tags steht beliebiger anderer Text (ohne eckige Klammern), der nicht verändert werden darf.
Die Aufgabe ist nun, alle schließenden Tags vom Anfang des Strings zu entfernen.
Bsp.:
Der String:schließend:[/_b]test[/_a]blub[/_d][_a]nach öffnendem Tag[/_a]
Soll nach dem Ersetzen mit preg_replace so aussehen:
schließend:testblub[_a]nach öffnendem Tag[/_a]
Das letzte schließende Tag darf nicht entfernt werden, da ein öffnendes davor steht. Nach dem ersten öffnenden Tag soll das Löschen abgebrochen werden.
Ich habe bisher nur Pattern hinbekommen, die mir entweder alle oder nur das erste schließende Tag entfernen.
-
Folgende Schleife erledigt dasselbe, aber eben nur für die ersten 100 Zeichen:
for($k = 0; $k < 100; $k++) { if($code[$k] == '[') { if($code[$k + 1] == '/') { $code = substr_replace($code, '', $k, 5); } else { break; } } }
Wenn ich 100 durch strlen($code) ersetze, klappt es zwar einwandfrei, aber es ist saulahm.
-
Hallo cd9000,
versuch's mal so:
<?php $code = "schließend:[/_b]test[/_a]blub[/_d][_a]nach öffnendem Tag[/_a]"; echo $code ."<p>"; $last = substr($code,strlen($code)-5); $code = preg_replace("#(.*?)[/_[a-z]](.*?)#si","\\1\\2",$code) . $last; echo $code; // $code enthält nun: // schließend:testblub[_a]nach öffnendem Tag[/_a] ?>
Bei Bedarf kannst du noch zwischen den \\1\\2 Leerzeichen o.ä. einbauen.
Bye.
-
Danke, aber die Zeile war nur ein Beispiel.
In Wirklichkeit kann alles nach dem ersten öffnenden Tag vorkommen, auch beliebig viele schließende Tags, die nicht entfernt werden dürfen.Ich brauche einen regulären Ausdruck (oder eine andere Idee), wie ich schließende Tags am Anfang des Strings entfernen kann, und zwar möglichst schnell.
Nach dem ersten öffnenden Tag darf aber nichts mehr gelöscht werden.Irgendwie bezweifle ich immer mehr, dass ein regulärer Ausdruck so viel schneller wäre. Das Problem ist zur Zeit, dass nur die nächsten 100 Zeichen validiert werden. Ein regulärer Ausdruck würde ja wieder alle Zeichen checken (möglicherweise zigtausend), auch wenn es sinnlos ist.
Ich habe jetzt folgende Variante:
if(preg_match('#^(.*?)\[_[a-z]\]#s', $code, $match_temp)) { $closing_tag_pos = strlen($match_temp[1]); $code = preg_replace('#\[/_[a-z]\]#', '', substr($code, 0, $closing_tag_pos)) . substr($code, $closing_tag_pos); } else { $code = preg_replace('#\[/_[a-z]\]#', '', $code); }
Mit dieser Variante bin ich eigentlich ganz zufrieden, denn sie macht genau das, was ich wollte, und zwar in annehmbarer Zeit.
Falls jemand aber einen besseren regulären Ausdruck kennt, immer her damit.
-
Hallo.
Nööö... also wenn du schon ne gute Lösung hast, dann hab ich keine besseren Vorschläge...
Bye.