Regulärer Ausdruck macht nicht ganz, was er soll
Stefano
- php
0 Texter mit x0 Stefano
1 suit0 Beat
Hallo,
Ich möchte aus einer URL die Seitenanzahl herauslöschen:
$url = preg_replace("!&site=(.*?)&!","&",$url);
Ich habe den Eindruck, dass das funktioniert, bis &site=123 nur einmal in der URL vorkommt. Zu 99% kann ich ohnehin davon ausgehen, dass das so ist.
Wie aber kann ich die RegEx umbauen, dass site=... auch mehrfach vorkommen darf und allesamt ersetzt werden?
Grüße, Stefan
Hallo,
Ich möchte aus einer URL die Seitenanzahl herauslöschen:
$url = preg_replace("!&site=(.*?)&!","&",$url);
Offenbar mehr als nur die Zahl.
Ich habe den Eindruck, dass das funktioniert, bis &site=123 nur einmal in der URL vorkommt. Zu 99% kann ich ohnehin davon ausgehen, dass das so ist.
Den Eindruck? Worauf berut der?
Und meinst Du "_solange_ &site=123 nur einmal in der URL vorkommt" oder wirklich "bis"?
Wie aber kann ich die RegEx umbauen, dass site=... auch mehrfach vorkommen darf und allesamt ersetzt werden?
In welchem Fall (konkretes Beispiel) wird es denn nicht ersetzt?
Wie aber kann ich die RegEx umbauen, dass site=... auch mehrfach vorkommen darf und allesamt ersetzt werden?
Eine Lösung mit parse_str() sagt dir nicht zu?
Eine Lösung mit parse_str() sagt dir nicht zu?
Doch, total. Kannte ich nur nicht.
Kannst Du mir trotzdem der Vollständigkeit halber sagen, wie ich alle site=... ersetzen würde?
Grüße, Stefan
Hello,
Eine Lösung mit parse_str() sagt dir nicht zu?
Doch, total. Kannte ich nur nicht.
Kannst Du mir trotzdem der Vollständigkeit halber sagen, wie ich alle site=... ersetzen würde?
Es gibt nur ein site=... in den geparsten Variablen.
1. parsen
2. unset($_parsed_vars['site'])
3. url neu aufbauen aus dem Ressourceanteil und den verbliebenen Elementen des Arrays
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Es gibt nur ein site=... in den geparsten Variablen.
- parsen
- unset($_parsed_vars['site'])
- url neu aufbauen aus dem Ressourceanteil und den verbliebenen Elementen des Arrays
Ja klar. Über den Lösungsweg weiß ich nun schon, wie ichs mache.
Trotzdem lässt mich nicht los, warum preg_replace nicht so gearbeitet hatte, wie ich dachte. Und das wurmt mich einfach.
$test="text&site=234&text2=www&site=567&site=54332&text";
$test = preg_replace("!&site=(.*?)&!","&",$test);
echo $test; // Ergebniss: text&text2=www&site=54332&text
Grüße, Stefan
$test="text&site=234&text2=www&site=567&site=54332&text";
$test = preg_replace("!&site=(.*?)&!","&",$test);
Weil das &site=567& findet und dann site=54332& nicht mehr macht - vermute ich.
$test="text&site=234&text2=www&site=567&site=54332&text";
$test = preg_replace("!&site=(.*?)&!","&",$test);
Weil das &site=567& findet und dann site=54332& nicht mehr macht - vermute ich.
Na, dann aber 3 Fragen hierzu:
Die Regex hat ja sowohl &site=234& gefunden und ersetzt, als auch &site=567&.
Grüße, Stefan
- Warum dann nur das letzte nicht?
- Wo ist die Logik dahinter?
$test="text&site=234&text2=www&site=567&site=54332&text";
$test="text <- kein match
&site=234& <- match
text2=www <- kein match
&site=567& <- match
site=54332&text"; <- kein match
Hallo,
Die Regex hat ja sowohl &site=234& gefunden und ersetzt, als auch &site=567&.
ja, jeweils einzeln.
- Warum dann nur das letzte nicht?
- Wo ist die Logik dahinter?
Der gesuchte Ausdruck wird einmal gefunden (und ggf. ersetzt). Dann ist dieser Teil des Patterns aus dem Suchmuster "verbraucht".
- Wie gestalte ich den Ausdruck entsprechend gieriger?
In deinem Sinn: Gar nicht. Einen Teil des Suchmusters mehrmals an verschiedenen Stellen zu finden, widerspricht dem Konzept: Pattern und der durchsuchte String lassen sich immer blockweise einander zuordnen, also jedem Abschnitt des Patterns entspricht auch ein Abschnitt im String (oder kann bei Verwendung der Quantifier ? oder * auch entfallen). Keinesfalls kann ein Abschnitt des Patterns mehreren Abschnitten im String entsprechen.
So long,
Martin
- Wie gestalte ich den Ausdruck entsprechend gieriger?
In deinem Sinn: Gar nicht.
Bestenfalls die funktion mehrfach aufrufen, in diesem speziellen fall sollte 2 Aufrufe reichen.
Hi,
$test="text&site=234&text2=www&site=567&site=54332&text";
$test = preg_replace("!&site=(.*?)&!","&",$test);
Weil das &site=567& findet und dann site=54332& nicht mehr macht - vermute ich.
Richtig vermutet.
Na, dann aber 3 Fragen hierzu:
Die Regex hat ja sowohl &site=234& gefunden und ersetzt, als auch &site=567&.
- Warum dann nur das letzte nicht?
Weil diese Fundstelle mit der vorherigen überlappt.
- Wo ist die Logik dahinter?
für einen weiteren Versuch wird NACH der vorherigen Fund-/Ersetzungsstelle begonnen.
Das & vor dem letzten Site ist Bestandteil der vorletzten Fund-/Ersetzungsstelle.
- Wie gestalte ich den Ausdruck entsprechend gieriger?
Indem Du das & am Anfang der Fundstelle nicht matchst, sondern per lookbehind einbindest.
Und auch gleich noch den Fall berücksichtigst, daß vor dem ersten Parameter kein & steht, sondern ein ?.
Und wenn Du schon dabei bist, auch gleich noch das ; als Parametertrennung berücksichtigen.
Ach ja, wenn der site-Parameter der letzte Parameter in der URL ist, wird er auch nicht ersetzt werden, da kein & mehr folgt.
Da der Parameterwert kein & oder ; enthalten darf, wäre es besser, statt (.*?)& besser [^&;]+ zu verwenden. Dann klappt's auch mit dem letzten Parameter.
Damit kommt es auch nicht mehr zu Überlappungen bei ?site=1&site=2, da das & dazwischen kein Bestandteil der Fund-/Ersetzungsstelle ist.
Die Ersetzung muß dann natürlich leer sein statt &
cu,
Andreas
für einen weiteren Versuch wird NACH der vorherigen Fund-/Ersetzungsstelle begonnen.
Das & vor dem letzten Site ist Bestandteil der vorletzten Fund-/Ersetzungsstelle.
Verstehe.
@Andreas:
Vielen Dank für Deine Ausführungen, die ich verstehe. Einige dieser Fallstricke hatte ich bereits durch weitere reg_replace umgangen. Aber jetzt verstehe ich wenigstens, woran der Versuch über meine Regex gescheitert war.
@Suit: Danke für den Tip mit parse_str().
Ich habe nun das ganze Konstrukt umgebaut und mithilfe von parse_url() und parse_str() die URL zerlegt und wieder zusammengesetzt.
In diesem Fall ist das wirklich die sinnvollste Lösung, da ich als Endprodukt einen sehr kontrollierten String zusammenbasteln kann.
Funktioniert übrigens vorzüglich.
Danke auch an alle anderen am Thread beteiligten User.
Grüße, Stefan
P.S: Eine Frage vielleicht noch: In der Doku zu parse_url() steht, dass sie nicht mit relativen URL funktioniert. Meine sind aber relativ und der array-wert "host", "path" und "query" greifen dennoch die richtigen Inhalte ab.
Ist das Zufall und muss ich mir deshalb jetzt Sorgen machen?
Ich habe nun das ganze Konstrukt umgebaut und mithilfe von parse_url() und parse_str() die URL zerlegt und wieder zusammengesetzt.
Zawinski | PCRE
---------+-----
1 | 0
:)
P.S: Eine Frage vielleicht noch: In der Doku zu parse_url() steht, dass sie nicht mit relativen URL funktioniert. Meine sind aber relativ und der array-wert "host", "path" und "query" greifen dennoch die richtigen Inhalte ab.
Das kommt darauf an, was du unter relativ verstehst :)
Wenn du damit einen absolute URL eben ohne protokoll und host meinst, ist er nicht relativ. Im Zweifelsfall knall einfach ein http://example.com davor und ignorier das beim zusammenbauen wieder.
Ich möchte aus einer URL die Seitenanzahl herauslöschen:
$url = preg_replace("!&site=(.*?)&!","&",$url);
Ich habe den Eindruck, dass das funktioniert, bis &site=123 nur einmal in der URL vorkommt. Zu 99% kann ich ohnehin davon ausgehen, dass das so ist.
Da hast du aber Glück, dass du dich nicht mit
'&'
versus HTML-gerechten '&' herumschlagen musst
Wie aber kann ich die RegEx umbauen, dass site=... auch mehrfach vorkommen darf und allesamt ersetzt werden?
Mit einer vernünftigen callback routine, welche deine URL sicher zerlegt und dann auf den query parts entsprechende Manipulationen vornimmt.
Da ist kein Grund anzunehmen, dass & der einzige legitime query part Separator ist.
mfg Beat
Mit einer vernünftigen callback routine, welche deine URL sicher zerlegt und dann auf den query parts entsprechende Manipulationen vornimmt.
Mit einer vernünftigen callback routine, welche deine URL sicher zerlegt und dann auf den query parts entsprechende Manipulationen vornimmt.
Was für ein idiotischer Funktionsname!
mfg Beat