Zeilenumbrüche nach bestimmten Elementen per RegEx entfernen
markus
- php
Hallo alle zusammen,
ich habe langen Textstring,
indem auch Zeilenumbrüche "\n" vorkommen.
Der String kommt aus einer Textarea.
Der String aus der Textarea kann BB-Codes enthalten,
und nachdem diese geparst sind, würde ich gern die Zeilenumbrüche ("\n") nach den Blocklevelelementen entfernen, um zu vermeiden, daß es sowas wie einen "doppelten" Umbruch gibt (Einmal der Umbruch durch das Blocklevelelement, und dann noch einen Umbruch, weil der Besucher im Formular nach einem Blocklevelement (bspw. einer Liste oder einer Zwischenüberschrift) NOCH einen Umbruch eingebaut hat)).
Eigentlich habe ich mir dazu einen RegEx gebaut,
der ganz am Ende, nachdem alle BB-Codes durch HTML ersetzt wurden,
laufen soll.
So soll bspw. ein <br /> nach einem </li> vermieden werden:
$text = preg_replace('/</li>\n/','</li>',$text);
Leider klappt das nun mal ganz und gar nicht...??
Hat jemand eine Idee, wo hier mein Denkfehler ist?
Hallö markus!
So soll bspw. ein <br /> nach einem </li> vermieden werden:
$text = preg_replace('/</li>\n/','</li>',$text);
Kann es sein, dass dein Zeilenumbruch durch "\r\n" dargestellt wird? Versuchs doch mal mit Suche nach "/</li>\s/"!
Oder ist dein Zeilenumbruch vielleicht schon zu HTML umgewandelt, z. B. per nl2br()?
Grüße aus Leipzig
willie
Hallo,
Kann es sein, dass dein Zeilenumbruch durch "\r\n" dargestellt wird? Versuchs doch mal mit Suche nach "/</li>\s/"!
hmm... habe gerade auch noch mal gesucht und bin auch schon auf das \s gestoßen - aber das bringt leider nichts.
Oder ist dein Zeilenumbruch vielleicht schon zu HTML umgewandelt, z. B. per nl2br()?
nein, ist er leider auch nicht...
vielleicht hole ich mal etwas weiter aus,
ich bin echt etwas am ende mit meinem latein.
aaaaalso:
wenn ein besucher BB-Code eingibt, wird dieser wie folgt umgwandelt:
// BB-Code durch richtige HTML Tags ersetzen
$arrHtml = array(
"[list]"=>"<ul>", "[/list]"=>"</ul>", //<ul></ul>
"[*]"=>"<li>", "[/*]"=>"</li>", //<li></li>
"[b]"=>"<strong>","[/b]"=>"</strong>", //<strong></strong>
"[i]"=>"<span font-style='italic'>", "[i]"=>"</span>", //<span></span>
"[hl]"=>"<h3>", "[/hl]"=>"</h3>", //<h3></h3>
"[quote]"=>"<div class='quote'>", "[/quote]"=>"</div>", //<div></div>
"[hr]"=>"</hr />", //<hr>
);
// Text durchgehen und nach o.g. Array ersetzen
foreach ($arrHtml as $key => $value) {
$text = str_replace( $key, $value, $text);
}
das klappt wunderbar, ohne probleme, alle BB-Codes werden ersetzt.
Ganz Ende lass ich dann noch folgendes los:
// sofern vorhanden, Zeilenumbrüche nach Blockelementen entfernen
$text = preg_replace('/</li>\n/',
'</li>',
$text);
// die verbliebenen Zeilenümbrüche in <br>-Tag umwandeln
$text = preg_replace('/\n/',"<br />",$text)
Damit will ich einfach mal nach <li>-Elementen den Umbruch entfernen.
Das zweite preg_replace, das \n zu <br> umwandelt, brauche ich aber, da ansonsten ja die "gewollten" zeilenumbrüche nicht umgewandelt werden...
ABER:
folgende eingabe in einer textarea:
[list]
[*]erster Punkt[/*]
[*]zweiter Punkt[/*]
[*]dritter Punkt[/*]
[/list]
wird im HTML dann zu
<ul>
<br /><li>erster Punkt</li><br /><li>zweiter Punkt</li><br /><li>dritter Punkt</li><br /></ul>
und das sieht natürlich echt komisch aus...
weiß denn da jemand rat?!?
Hallö nochmal,
ich bin ja nun nicht _der_ PHP-Profi... Aber das hier ist mir grad aufgefallen:
$text = preg_replace('/</li>\n/',
................................^
Stimmt das denn? (Stand im Eingangsposting nicht so.)
Grüße aus Leipzig
willie
Hallo Markus!
So soll bspw. ein <br /> nach einem </li> vermieden werden:
$text = preg_replace('/</li>\n/','</li>',$text);
Kann es sein, dass dein Zeilenumbruch durch "\r\n" dargestellt wird? Versuchs doch mal mit Suche nach "/</li>\s/"!
willie.de hat recht!
Tatsache ist ein Zeilenumbruch kann mit "\r\n" dargestellt werden! Die Darstellung mit "\n" reicht aus, ergo, schreib mal folgendes in deinen Code:
$text = str_replace ("\r","",$text);
Ciao,
Andy
Hallo Andy,
Tatsache ist ein Zeilenumbruch kann mit "\r\n" dargestellt werden! Die Darstellung mit "\n" reicht aus
Jain. \n ist die Version, wie sie in der Unix-Welt vorherrscht. Unter Windows wird das von manchen Programmen jedoch nicht als Zeilenumbruch dargestellt, da dort \r\n verwendet wird. Außerdem wurde noch bis zu Mac OS 9 auf Macs \r für einen Zeilenumbruch verwendet ;-)
Schöne Grüße,
Johannes
Hallo Johannes
Tatsache ist ein Zeilenumbruch kann mit "\r\n" dargestellt werden! Die Darstellung mit "\n" reicht aus
Jain. \n ist die Version, wie sie in der Unix-Welt vorherrscht. Unter Windows wird das von manchen Programmen jedoch nicht als Zeilenumbruch dargestellt, da dort \r\n verwendet wird. Außerdem wurde noch bis zu Mac OS 9 auf Macs \r für einen Zeilenumbruch verwendet ;-)
Hab ich mir schon gedacht, dass jemand daran noch rumbohren wird! :-) Ist mir bekannt, das \r allein auf Mac für den Zeilenumbruch steht. Ist aber eigentlich vernachlässigbar, da ich mal denke, das Browser auf dem Mac ein \r\n oder \n schicken werden und nicht ein \r! (*)
Weiterhin auch Tatsache, dass \n allein von der Windowswelt in manchen Programmen nicht gut ankommt.
Aber: Man muss sich im Klaren sein, wir reden über Internetanwendungen, da darf es eigentlich sowas wie Betriebssystemabhängige Zeilenumbrüche gar nicht geben, soll heißen, dem Browser muss es egal sein, ob da \r\n oder \n steht, er hat im Quelltext gefälligst einen Zeilenumbruch anzuzeigen! Und sagen wir es kurz ein einzelnes \n ist immer noch ein Byte kürzer als ein \r\n! :-)
Und ansonsten könnte man sich noch eine Ersetzungsvariante überlegen, die ein \r und ein \r\n in ein \n umwandelt. Wollte es halt einfach halten.
(*) Hier wäre natürlich ein Erfahrungsbericht nicht verkehrt. Was schicken Mac-Browser an den Webserver? Doch nur ein \r?
Ciao,
Andy
Hallo Andy,
Aber: Man muss sich im Klaren sein, wir reden über Internetanwendungen, da darf es eigentlich sowas wie Betriebssystemabhängige Zeilenumbrüche gar nicht geben, soll heißen, dem Browser muss es egal sein, ob da \r\n oder \n steht, er hat im Quelltext gefälligst einen Zeilenumbruch anzuzeigen! Und sagen wir es kurz ein einzelnes \n ist immer noch ein Byte kürzer als ein \r\n! :-)
Aber zumindest in HTTP wird CRLF also \r\n als Ende einer Zeile definiert: http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2. Aber wie auch sonst gilt hier wieder dieser Grundsatz der Netzwerk-Programmierung: »be liberal in what you accept, conservative in what you send.«
In diesem Beispiel also: Sende \r\n als Zeileende aber akzeptiere auch die anderen Varianten.
Und ansonsten könnte man sich noch eine Ersetzungsvariante überlegen, die ein \r und ein \r\n in ein \n umwandelt. Wollte es halt einfach halten.
Mit str_replace(array("\r\n","\r"), "\n", $text);
dürftest du das gewünschte Ergebnis erzielen.
(*) Hier wäre natürlich ein Erfahrungsbericht nicht verkehrt. Was schicken Mac-Browser an den Webserver? Doch nur ein \r?
Zumindest ab Mac OS X, das ja ein Unix ist, wird intern auch \n verwendet.
Schöne Grüße,
Johannes