Bernhard Häussner

Howto: Alleinstehende Unds für XHTML umwandeln

16.04.2009, 13:22
$text=preg_replace ('/&(?!amp;|quot;|nbsp;|gt;|lt;|laquo;|raquo;|copy;|reg;|#[0-9]{1,5};|#x[0-9A-F]{1,4};)/','&', $text);

In meinem Markup-Parser für diesen Blog hatte ich das Problem, dass ich zwar einzelne & in &amp; umwandeln konnte, damit ich Et-Zeichen im ganz normalen Text schreiben kann, auf der anderen Seite aber auch HTML <tags> erlauben will. Wenn ich jetzt aber über HTML schrieben will, muss ich ja auch irgendwie die größer und kleiner-Zeichen encodieren, damit nicht alles einfach vom Browser gerendert wird. Wenn ich aber ein &lt; eingebe, würde das Kaufmanns-Und sofort zu &amp; umgewandelt und so würde dann im Quelltext &amp;lt; stehen und im Text nicht < sondern &lt;. Also brauchte ich eine Methode um nur einzelne kaufmännische Unds zu finden. Das lief dann auf obigen Regulären Ausdruck hinaus.

Er ersetzt & mit &amp; nur dann, wenn dahinter keines der HTML-Entities folgt. Da es eine sehr lange Liste von benannten HTML-Entities gibt, habe ich nur die aufgenommen, die man in HTML Umwandeln muss („htmlspecialchars“), damit ihre Bedeutung erhalten bleibt und ein paar Sonderzeichen, die ich sonst nie finde. Alles andere (z.B. &eacute; für é, 文字, ...) wird ja von UTF-8 abgedeckt. Für ASCII kann man auch noch die dezimale oder hexadecimale Unicode-Notierung verwenden.

Der regexp verwendet eine Erweiterung, die Negative Vorausschau (?!x). Das ist so etwas wie ein Unter-Ausdruck, der zwischendurch überprüft wird am Text nach der aktuellen Position. Die Buchstaben, die auf den überprüften Ausdrück passen, werden nicht mit "gefressen", sie werden also nicht übersprungen, sondern nur kurz getestet. Nur wenn der Ausdruck nicht zutrifft wird von der Ursprungsposition weiter getestet. Es gibt natürlich auch noch positive Vorausschau (?=x) (die weiter laufen lässt, wenn der Ausdruck passt), sowie positive (?<=x) und negative (?<!x) Zurückschau (die jeweils den Text vor der aktuellen Position prüfen).

Das würde zum Beispiel alle Minuskeln ausgeben, die nach einem „o“ stehen: [a-z](?<=o.). Man beachte den Punkt nach dem „o“. Er steht für das gerade überlaufene Zeichen für das jetzt geprüft wird was (von der aktuellen Position hinter dem Zeichen aus gesehen) davor steht. Das bedeutet in der Rücksicht sieht sich das Zeichen nochmal selbst. Noch ein Beispiel: .(?<=o(?#comment).{5}) findet alle Zeichen 5 Positionen vor „o“.

Diese Features stehen in Ruby übrigens nur teilweise zur Verfügung.

Kurze URL http://1-co.de/b/z. Post to twitter

Kommentare

keine





 
Χρόνογραφ
© 2008-2017 by Bernhard Häussner - Impressum - Login
Kurz-Link zu dieser Seite: http://1-co.de/b/z