php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 22.08.2009, 17:48  
Benutzer
 
Benutzerbild von dunst0
 
Registriert seit: 30.07.2009
Beiträge: 56
PHP-Kenntnisse:
Fortgeschritten
dunst0 befindet sich auf einem aufstrebenden Ast
Standard

@nikosch :
hast du ein info parat wo man das nachlesen kann?
__________________
signatur was ist das denn,
davon hab ich noch nie gehört
dunst0 ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 23.08.2009, 01:00  
Erfahrener Benutzer
 
Benutzerbild von Mati_
 
Registriert seit: 27.06.2009
Beiträge: 107
PHP-Kenntnisse:
Fortgeschritten
Mati_ befindet sich auf einem aufstrebenden Ast
Mati_ eine Nachricht über ICQ schicken Mati_ eine Nachricht über MSN schicken
Standard

Zitat:
Zitat von dunst0 Beitrag anzeigen
hast du ein info parat wo man das nachlesen kann?
Die habe ich auch: Im PHP-Manual und direkt bei der pcrepattern-manpage.

dunst0, deine Überlegung bzgl. die jeweils tiefste Ebene zu substituieren ist schon richtig, in die andere Richtung geht es, wie nikosch schon erwähnte, mit dem Rekursionselement aber auch. Wie die Regex-Maschine da in etwa vorgeht habe ich an anderer Stelle schonmal erläutert.

Du gehst aber ziemlich ungünstig vor, indem du jedwedes auftreten eckiger Klammern verbietest - schließlich sind es das nur zugehörige öffnende/schließende Tags. Und wie kann man eine Negation ganzer Zeichenpassagen erzeugen? Mit Lookarounds. Mit zB. folgendem regulären Ausdruck kann man das jeweils innerste Element matchen:
Code:
\[([^]]+)](?:(?:(?!\[/?\1]).)+)\[/\1]
Der Inhalt des gefundenen Tags wird eingefangen, und fortan wird nach jedem Character überprüft ob ein öffnendes oder schließendes Komplement vorhanden ist – wenn nein wird ein weiteres Zeichen gematcht, wenn ja wird probiert mit dem schließendem Komplement zu matchen. Wenn das nicht der Fall ist, schlägt der reguläre Ausdruck fehl und beginnt an dem Fehlschlag von neu.

Bei [b]a[b]b[/b]a[/b] schlägt nach dem a der Lookahead fehl, es wird mit dem matching des schließenden Komplements fortgesetzt, da das aber fehlschlägt beginnt der Ausdruck wieder von vorne. Derselbe Ablauf wieder, nur nach dem b wird der schließende Tag erfolgreich gematcht.

Auf der Funktionsreferenz zu preg_replace_callback findet sich übrigens ein Parsing-Beispiel, ich machte jedoch eine interessante Entdeckung die ich mir nicht erklären konnte:

Bei dem Beispiel wird die Methode mit dem Rekursionselement genommen, wodurch bei jedem Durchlauf das äußerste Element gematcht wird. Es wird immer wieder die Funktion mit dem Ergebnis als Parameter aufgerufen, anscheinend solange bis kein Treffer mehr gefunden wurde. Umgekehrt, mit der Methode „jeweils innerstes Element“ funktioniert es jedoch nicht. Ich habe es probiert, wenn man es manuell in einer Schleife mehrfach aufruft funktioniert es genauso, mit der rekursiven Funktion aber nicht.


p.s.: Den Ausdruck für das innerste Element kann man ganz nach dem Beispiel auf php.net auch mit einer Alternation gestalten, also
Code:
\[([^]]+)](?:[^[]|(?!\[/?\1])\[)+\[/\1]
Eventuell die beiden Ausdrücke mal vergleichen und ein wenig überlegen, warum die auf das gleiche Ergebnis kommen, gute Übung.

Geändert von Mati_ (23.08.2009 um 23:16 Uhr). Grund: Ein literales [ vergessen
Mati_ ist offline   Mit Zitat antworten
Alt 23.08.2009, 03:33  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Zitat:
Bei dem Beispiel wird die Methode mit dem Rekursionselement genommen, wodurch bei jedem Durchlauf das äußerste Element gematcht wird. Es wird immer wieder die Funktion mit dem Ergebnis als Parameter aufgerufen, anscheinend solange bis kein Treffer mehr gefunden wurde. Umgekehrt, mit der Methode „jeweils innerstes Element“ funktioniert es jedoch nicht. Ich habe es probiert, wenn man es manuell in einer Schleife mehrfach aufruft funktioniert es genauso, mit der rekursiven Funktion aber nicht.
Wie meinst Du das? Das innerste Element enthält doch keine weiteren. Ergo keine Rekursion?! Oder wie jetzt?
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 23.08.2009, 08:21  
Benutzer
 
Benutzerbild von dunst0
 
Registriert seit: 30.07.2009
Beiträge: 56
PHP-Kenntnisse:
Fortgeschritten
dunst0 befindet sich auf einem aufstrebenden Ast
Standard

ohh ... auch einem aufmerksamen PHP-Manual leser entgeht mal was.
Danke für den hinweis..das lese ich mir durch ....

Momentan funktioniert mein code und parst alle bbcodes, aber erstellt bei schlechten bbcode, schlechten html

aus:
Code:
[test]hah[muh]test[/test]tut[/muh]
wird:
Code:
<test>hah<muh>test</test>tut</muh>
kann man das mit Rekursion oder Lookahead verhindern?

hmm ich versuche grad Rekursion aber noch habe ich mich nicht
durch gearbeitet, muss wohl noch weiter nachlesen und probieren


uii ich hab apache abstürzen lassen mit meinen versuchen cool
mein regulärer ausdruck muss ja gar schlecht gewesen sein
__________________
signatur was ist das denn,
davon hab ich noch nie gehört

Geändert von dunst0 (23.08.2009 um 08:25 Uhr).
dunst0 ist offline   Mit Zitat antworten
Alt 24.08.2009, 00:03  
Erfahrener Benutzer
 
Benutzerbild von Mati_
 
Registriert seit: 27.06.2009
Beiträge: 107
PHP-Kenntnisse:
Fortgeschritten
Mati_ befindet sich auf einem aufstrebenden Ast
Mati_ eine Nachricht über ICQ schicken Mati_ eine Nachricht über MSN schicken
Standard

Zitat:
Zitat von nikosch Beitrag anzeigen
Wie meinst Du das? Das innerste Element enthält doch keine weiteren. Ergo keine Rekursion?! Oder wie jetzt?
Methode 1 (mit Rekursionselement, das Beispiel auf php.net): Die jeweils höchste Ebene wird ersetzt.
[b]a[b]c[/b]a[/b] nach 1. Durchlauf <b>a[b]c[/b]a</b> nach 2. Durchlauf <b>a<b>c</b>a</b>

Methode 2: Die jeweils tiefste Ebene wird ersetzt.
[b]a[b]c[/b]a[/b] nach 1. Durchlauf [b]a<b>c</b>a[/b] nach 2. Durchlauf <b>a<b>c</b>a</b>

Die zweite Methode funktioniert jedoch nicht mit der rekursiven Funktion im php.net-Beispiel, obwohl sie nach x-mal manuellen ausführen genau das gleiche Ergebnis wie ersteres liefert (wobei x die maximale Tiefe ist).


@dunst0: Dann müsste man mit dem Lookahead ein auftreten sämtlicher anderer Tags verbieten, und nicht nur gleicher. Eine kleine Modifizierung des obigen:
Code:
\[([^]]+)](?:(?:(?!\[/?[^]]+).)+)\[/\1]

Geändert von Mati_ (24.08.2009 um 00:09 Uhr).
Mati_ ist offline   Mit Zitat antworten
Alt 24.08.2009, 13:00  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Zitat:
Methode 2: Die jeweils tiefste Ebene wird ersetzt.
aca nach 1. Durchlauf a<b>c</b>a nach 2. Durchlauf <b>a<b>c</b>a</b>

Die zweite Methode funktioniert jedoch nicht mit der rekursiven Funktion im php.net-Beispiel, obwohl sie nach x-mal manuellen ausführen genau das gleiche Ergebnis wie ersteres liefert (wobei x die maximale Tiefe ist).
Der Begriff "Rekursion" sagt doch imho aus, dass nur das Innere des gematchten Teils nochmals untersucht wird. Rekursion nach außen gibts auch in normaler prozeduralen Programmierung nicht, weil das umschliessende Element ja nicht bekannt ist.
Und in einer Schleife wird ja immer wieder ganz aussen angefangen. In meinen Augen völlig logisch.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 24.08.2009, 13:15  
Erfahrener Benutzer
 
Benutzerbild von Mati_
 
Registriert seit: 27.06.2009
Beiträge: 107
PHP-Kenntnisse:
Fortgeschritten
Mati_ befindet sich auf einem aufstrebenden Ast
Mati_ eine Nachricht über ICQ schicken Mati_ eine Nachricht über MSN schicken
Standard

Ich spreche bei Methode 2 ja auch nicht von Rekursion. Bei Methode 1 wird durch Rekursion im regulären Ausdruck die äußerste Ebene gefunden, bei Methode 2 durch einfachen Lookahead die innerste.

Beide Methoden brauchen gleich viele Durchläufe um alles zu substituieren. Bei dem Beispiel auf php.net ist die Ebenentiefe 2, demnach werden auch zwei preg-Aufrufe benötigt um alles zu ersetzen. Mit der oben geschilderten zweiten Methode werden auch zwei Durchläufe benötigt, doch werden diese, wenn man die rekursive Funktion auf php.net übernimmt, nicht durchgeführt.

Da fragte ich mich halt, wann stoppt diese rekursive Funktion auf php.net? Ich nahm an, wenn der Ausdruck nicht mehr matcht, aber dem scheint nicht so.

Hoffe, du verstehst wie ich das meine.
Mati_ ist offline   Mit Zitat antworten
Alt 24.08.2009, 13:22  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Nee. Welches Bsp. meinst Du? #3? Da ist doch eine Rekursion drinnen: (?R)).
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 24.08.2009, 20:30  
Erfahrener Benutzer
 
Benutzerbild von Mati_
 
Registriert seit: 27.06.2009
Beiträge: 107
PHP-Kenntnisse:
Fortgeschritten
Mati_ befindet sich auf einem aufstrebenden Ast
Mati_ eine Nachricht über ICQ schicken Mati_ eine Nachricht über MSN schicken
Standard

Ok, ich versuch's nochmal.

In Beispiel 3 auf der Dokumentation von preg_replace_callback, wird beim dortigen regulären Ausdruck durch Rekursion die jeweils höchste Ebene gefunden. Nach dem ersten Durchlauf der Funktion gibt es aber noch die tieferliegenden Ebenen (haue mal ein var_dump($eingabe) in die Funktion und führe das Beispiel aus). Also muss das ganze nochmal durchlaufen werden, solange, bis man zur tiefsten Ebene vorgedrungen ist. Bei der dortigen Funktion geht dieser mehrfache Funktionsaufruf automatisch - beim return wird die Funktion ja nochmals aufgerufen, solange bis es eben genügend preg-Aufrufe gab.

Nun gibt es aber noch die Möglichkeit den regulären Ausdruck zu ersetzen mit dem auf der vorherigen Seite geposteten - und mit diesem wird die jeweils tiefste Ebene nach dem ersten Durchlauf bzw. preg-Aufrufes ersetzt. Doch diesmal wird die Funktion selbst nicht mehrfach rekursiv aufgerufen um alle Substitutionen durchzuführen - und das ist die Merkwürdigkeit.
Mati_ ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
In Funktion auf Variablen außerhalb zugreifen Cartman1984 PHP Tipps 2009 7 03.06.2009 19:55
[Erledigt] Variablen mittels POST übergeben pierrebln PHP Tipps 2009 10 27.03.2009 09:21
[Erledigt] Variablen in andere Dateien übergeben Nobs PHP Tipps 2009 12 12.02.2009 09:15
Event ändern und dabei variablen übergeben cycap JavaScript, Ajax und mehr 8 14.05.2008 07:32
Alle Variablen einer Funktion in andere übergeben MaMo-Net PHP-Fortgeschrittene 9 22.10.2005 19:22
Wie kann man alles Variablen übergeben ?? PHP Tipps 2005-2 14 11.09.2005 22:19
Variablen werden per post nicht übergeben sinai PHP Tipps 2005-2 9 12.08.2005 10:04
(schnellere) Funktion zum Zusammenfassen von CSS PHP-Fortgeschrittene 21 08.08.2005 16:47
Variablen an den Interpreter übergeben PHP Tipps 2005-2 24 04.07.2005 21:43
Variablen werden nicht übergeben PHP Tipps 2005-2 6 26.06.2005 22:08
[Erledigt] Wie kann ich beliebig viele Werte an eine Funktion übergeben PHP Tipps 2005 11 25.01.2005 10:44
komplexe Variablen übergeben? PHP Tipps 2004-2 8 02.12.2004 08:29
[Erledigt] Parameter an eine funktion übergeben PHP Tipps 2004 9 18.08.2004 14:14
Variablen per adresse übergeben rocco PHP Tipps 2004 7 24.07.2004 12:03
[Erledigt] Referenz auf Funktion übergeben PHP-Fortgeschrittene 7 20.07.2004 09:51

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
anonyme funktion php parameter, php anonyme rekursive funktion, werte an anonyme funtkionen übergeben, js anonymen funktionen parameter übergeben, javascript this an anonyme funktion übergeben, javascript wert in anonyme funktion, js anonyme funktion übergeben, php anonyme funktionen rekursiv, js anonyme funktion, javascript anonyme funktion, javascript anonyme funktionen, php rekurive funktion erster durchlauf, javascript anonyme funktionen variablen, variable anonyme funktion, js this an anonyme funktion übergeben, anonymen funktionen übergeben, javascript variable an anonyme funktion übergeben, javascript anonyme funktion rekursiv, php anonyme funktion, php regulär äußerste tags

Alle Zeitangaben in WEZ +2. Es ist jetzt 00:47 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum