php.de

Zurück   php.de > php.de Intern > Wiki Diskussionsforum > Tutorials

Tutorials Hier findest Du Tutorials, welche nach und nach ein fertiges Script ergeben. Sehen, lernen & verstehen!

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 12.09.2006, 10:06  
Erfahrener Benutzer
 
Registriert seit: 03.01.2006
Beiträge: 253
CC84
Standard Tutorial: BB-Code Verschachtelungen mal anders gelöst

Inspiriert von dem anderen Thema, das mir persönlich zu viel Textmanipulationen beinhaltet habe ich mir die letzten Tage mal Gedanken gemacht, wie man das ganze eventuell einfacher lösen kann.
Nachdem ich die meisten Ideen wieder verworfen habe, habe ich nun eine Version gefunden, die in meinen Augen recht schnell und vor allem recht kurz sein sollte und dabei nur kleine Nachteile mit sich bringt.

Zuerst einmal der Text, den ich auseinander nehmen möchte:

Code:
$text = "blablabla 
Zitat:
blubb
Zitat:
Zitat von bla
text
" . "WAHHHWAHHH
Zitat:
*grml*
huhuhu";
Das größte Problem ist es bei allen Varianten die passenden Tags zu finden.

Ich fange daher damit an, den String nach allen String die in [] geschrieben sind zu filtern.

PHP-Code:
preg_match_all('{\[(/?.*)(=.*)?\]}Usmi',$text,$hits,PREG_OFFSET_CAPTURE); 
Dieser Reguläre Ausdruck liefert in $hits ein Array zurück das aus 3 weiteren Arrays besteht.

Im ersten Array werden die gematchten Zeichenketten zurück gegeben.

Im zweiten Array werden der Teil zurück gegeben, der durch diesen Ausdruck gematched wurde: (/?.*)

und im dritten dann dieser (=.*).

Desweiteren sorgt der Parameter PREG_OFFSET_CAPTURE dafür dass jedes gefundene Element als Array zurück gegeben wird. Dabei enthält [0] den String und [1] die Position an der dieser String im text steht.

Die Aufteilung in die 3 Arrays hat für uns den Vorteil, dass wir bereits Zusätzliche Infos wie den Autor des zitierten Texts oder eine URL aus dem URL Tag heraus gefiltert haben.

Im weiteren Verlauf ist nur Array 2 und 3 (Position [1] und [2]) für mich interessant.

Zuerst definiere ich nun die erlaubten Tags:

PHP-Code:
$tags = array('quote','b'); 
Dann durchlaufe ich die gefundenen Elemente, mit der Absicht Paare zu finden.

Dazu dient das Array $hits[1] (Wir erinnern uns, da stehen die tags drin.)

Es wird unterschieden, haben wir das reine Tag wie etwa quote oder ein /tag wie /quote.

Öffnende Tags werden grundsätzlich akzeptiert, sofern sie erlaubt sind und in $openers geschrieben. Zusätzlich werden die Infos aus $hits[2] wie ein =Autor in das Array $additionals geschrieben.

Wurde ein schliessendes Tag gefunden, wird kontrolliert, ob dieses Tag gerade geöffnet wurde. (Letzte Element auf $openers muss dann das Tag sein)
Wenn ja, dann haben wir ein Paar gefunden. und wir schreiben zuerst den Öffner mit den zusätzlichen Informationen gefolgt von Schließer auf das array $pairs.

Da beim array_pop das Element aus dem Array entfernt wird, müssen wir es wieder einfügen, wenn es nicht gematcht hat.

PHP-Code:
foreach ($hits[1] as $key => $tag){
    if (
in_array($tag[0],$tags)){
        
$openers[] = $tag;
        
$additionals[] = isset($hits[2][$key][0]) ? $hits[2][$key][0] : ''
    }
    elseif (
$tag[0][0] == '/' AND in_array(substr($tag[0],1),$tags)){
        
$last array_pop($openers);
        if (
$last[0] == substr($tag[0],1)){
            
$pairs[] = array('opentag' => $last[0], 'offset' => $last[1], 'additional' => array_pop($additionals));
            
$pairs[] = array('closetag' => $tag[0], 'offset' => $tag[1]);
        }
        else 
array_push($openers,$last);
        
    }

Aus dieser Vorgehensweise ergibt sich der einzige mir bekannte Nachteil. Sollte jemand vergessen ein Tag zu schließen, können alle davor liegenden Tags nicht wieder geschloßen werden.
Desweiteren erwartet diese Funktion, dass Tags wie bei XML üblich öffner und schließer nicht verdreht werden dürfen. Ein würde also Probleme machen. Das /b würde ignoriert und damit das
Code:
[b]
nie mehr verlassen.

Als Resultat haben wir das Array $pairs, das wir nun streng genommen nur noch durchlaufen müssen und alle Tags ersetzen.
Dank des Offsets ist dies mit substr_replace kein Problem.
Der einzige Hacken liegt hier jedoch darin, dass wenn ein Tag durch html Code mit einer anderen Länge ersetzt wird, die später liegenden Offsets ungültig sind.
Da Zudem die Offsets nicht sauber durchlaufen, ist eine Korrektur nicht so einfach machbar.

Genau aus diesem Grund wurden Schließer und Öffner getrennt in $pairs eingetragen. Da sicher ist, dass in dem Array nur Tags stehen, die auch einen Partner haben, können wir sie nun getrennt betrachten.

Um das Offset Problem zu beheben. Sortiere ich das Array einfach Absteigend nach dem Offset.

PHP-Code:
function sortByOffset($a,$b){
    if (
$a['offset'] == $b['offset']) {
        return 
0;
    }
    return (
$a['offset'] > $b['offset']) ? -1;

uasort($pairs,"sortByOffset"); 
Nun muss ich nur noch meine Ersetzungen durchführen. In meinem Beispiel mal für
Code:
[quote] und [b]
PHP-Code:
foreach ($pairs as $pair){
    if (isset(
$pair['opentag'])){
        if (
$pair['opentag'] == 'quote')
            
$text substr_replace($text,"<fieldset><legend>Zitat:".substr($pair['additional'],1)."</legend>",$pair['offset']-1,strlen($pair['opentag'].$pair['additional'])+2);
        if (
$pair['opentag'] == 'b')
            
$text substr_replace($text,"[b]",$pair['offset']-1,strlen($pair['opentag'])+2);
    }
    else{
        if (
$pair['closetag'] == '/quote')
            
$text substr_replace($text,"</fieldset>",$pair['offset']-1,strlen($pair['closetag'])+2);
        if (
$pair['closetag'] == '/b')
            
$text substr_replace($text,"[/b]",$pair['offset']-1,strlen($pair['closetag'])+2);
    }

Ich nutze in diesem Fall substr_replace und arbeite mich von hinten nach vorne durch. Für die Länge des zu ersetzenden Tags berechne ich einfach die Länge des Tags und eventuell der zusätzlichen Information.
Da ich nur das quote in $pairs stehen habe, muss ich hier ein Zeichen früher anfangen um die [ mit zu löschen und dafür dann 2 Zeichen mehr ersetzen.

Im Gegensatz zu dem anderen hier erhältlichen Tutorial ist dieses hier bedeutend kompakter zu schreiben und manipuliert zudem nur wenig im Text rum.

Über Meinungen würde ich mich freuen. Und wenn das jemand noch in die Tutorials verschieben könnte wäre es noch besser.

Aus dem oben angegeben Code wird dan:
Code:
blablabla
	<fieldset>
		<legend>Zitat:</legend>
		blubb
		<fieldset>
			<legend>Zitat:bla</legend>
			text
		</fieldset>
		WAHHHWAHHH
		<fieldset>
			<legend>Zitat:</legend>
			*grml*
		</fieldset>
	</fieldset>
huhuhu
CC84 ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

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

Alt 18.09.2008, 20:46  
Erfahrener Benutzer
 
Registriert seit: 03.01.2006
Beiträge: 253
CC84
Standard

Hm seit langem hier mal wieder rein gesehen.

Mein Tutorial hats ja mit der Umstellung leider völlig zerschoßen.

Editieren darf/kann ich es nicht mehr. Da ich den BBCode zu dem Titel auch nicht mehr habe, kann ich es leider auch nicht so ohne weiteres korrigieren. Vielleicht kann mir ja ein Mod mal den Plaincode aus der DB zukommen lassen.
CC84 ist offline   Mit Zitat antworten
Alt 18.09.2008, 20:59  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 34.253
PHP-Kenntnisse:
Fortgeschritten
nikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz seinnikosch kann auf vieles stolz sein
Standard

Bitteschön...
__________________
--
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 gerade online   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
Probleme mit PHP Code HappyDieMuschel PHP Tipps 2008 7 28.05.2008 06:34
[Erledigt] PHP Code aus Datenbank ayti PHP Tipps 2008 8 26.05.2008 19:40
Design und Code Trennen TeazY PHP Tipps 2008 29 21.05.2008 12:08
Nur bestimmten Html Code zulassen? litterauspirna PHP Tipps 2008 5 29.04.2008 12:30
einfacher Code zum Einbinden von "Inhaltsbereichen" MaxDittmann PHP-Fortgeschrittene 6 01.10.2007 15:54
ordner zippen (etwas code schon vorhanden) EvilDragon PHP Tipps 2007 3 18.11.2005 12:15
bb code in htm code wandeln janni PHP Tipps 2007 2 04.11.2005 22:36
Tutorial gesucht... Datenbanken 3 16.09.2005 08:54
JS Code in PHP Code?? HTML, Usability und Barrierefreiheit 12 08.08.2005 15:45
Seite 1/2/3..Code was haltet ihr davon? Matthiasnet PHP Tipps 2005-2 4 29.07.2005 20:29
[Erledigt] Lesbarkeit von Code Off-Topic Diskussionen 6 14.07.2005 14:48
code aus db mit eval replacen chief-thomson PHP Tipps 2005-2 4 08.07.2005 15:33
Trennung von Layout und Code (Tutorial?) PHP Tipps 2005-2 2 21.06.2005 17:14
[Erledigt] wie schreibt man sauberen Code? Off-Topic Diskussionen 18 22.09.2004 22:33
Problem mit COde PHP Tipps 2004 5 28.08.2004 16:04

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php bbcode tutorial, bbcode tutorial, bb code tutorial, bbcode verschachtelung, bb tutorial, php bbcode quote, bbcode tutorial php, raum verschachtelungen, bb code php quote, php bbcode zitat, php bb codes tutorial, verschachtelungen von tags, phpbb bbcode tutorial, php verschachtelungen, bbcode fieldset, php bbcode tutorial -regex, bb code verschachtelung, bb codes tutorial php, vbulletin quote bbcode fieldset, bbcode verschachteln phpboard

Alle Zeitangaben in WEZ +1. Es ist jetzt 18:49 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

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.