Mit preg-replace (regex) xhtml validieren (html tags schließen)

matzebrock

Grünschnabel
Hallo. Ich brauche mal eure Hilfe.

Angenommen ich habe nen String in dem nun eine ganze Reihe von HTML-Tags stehen.
z.B.


PHP:
$html = '<a href="tutorials.de">Link</a><br><br />
<img src="abc.gif" /><p>Ein Absatz</p><hr><br /><input type="text">';

In diesem Beispiel ist nen simpler HTML Code, der jedoch nicht XHTML Konform ist.
Meine Frage nun:
Wie müsste der Regex-Ausdruck heißen, damit nur die Tags (<hr>; <br>; <img>; <input> - also nur alleinstehende tags), die offen sind, geschlossen werden? Also dass aus dem oberen Beispiel


PHP:
$html = '<a href="tutorials.de">Link</a><br /><br />
<img src="abc.gif" /><p>Ein Absatz</p><hr /><br /><input type="text" />';

Mit dem Regex Ausdruck müsste lediglich nach bestimmten Tags gesucht werden - den Tag an sich auslesen - nachgucken ob an vorletzter Stelle ein "/" steht - wenn nicht an dieser stelle einfügen.

Bitte versucht mir zu helfen. Danke!

Gruß
Matze
 
Geht es nicht so?

PHP:
$html = '<a href="tutorials.de">Link</a><br><br /> 
<img src="abc.gif" /><p>Ein Absatz</p><hr><br /><input type="text">';  

$suchstring = "<br>";
$xHtmlString = "<br />";


$html = str_replace ($suchstring,$xHtmlString,$html);
 
Hallo danke für deine Antwort.
In diesem Fall würde es so gehen (also bei <br>).
Aber bei Input - bei dem der Tag-Content immer anders kann ich nicht str_replace nehmen.

Ich bin gerade so weit:

PHP:
$shorttags = array('img', 'input', 'hr', 'br');
unset($ausgabe);
foreach ( $shorttags as $tag ) {
	$pattern = "/<".$tag.".*?>/i";
	preg_match_all($pattern, $html, $ausgabe[$tag]);
}

Das liefert mir zumindest alle Tags, die es zu ersetzen gilt - leider auch die, bei denen das Slash (z.B. <br />) schon vorhanden ist. Die müsste ich jetzt ausschließen können.

Dann der Replace...
 
Wäre es denn so schlimm, wenn du auch diese noch mal ersetzt? Also aus einem <br /> einfach noch mal ein <br /> machst? Ist ein wenig unsauber programmiert, erspart dir aber eine Menge Zeit ;-)

Gruß
Chris
 
Folgender Code funktioniert zwar, aber ziemlich langsam...

PHP:
$shorttags = array('img', 'input', 'hr', 'br');
		
foreach ( $shorttags as $tag ) {
	unset($ausgabe);
	$pattern = "/<".$tag.".*?>/i";
	preg_match_all($pattern, $html, $ausgabe);
				
	foreach ( $ausgabe[0] as $replace ) {
		if ( strpos($replace, '/>') == 0 ) {
			$html = str_replace($replace, substr($replace, 0, strlen($replace)-1) . ' />', $html);
			$html = str_replace('</'.$tag.'>', '', $html);
		}
	}
}

Deshalb würde ich mich über eine preg_replace Lösung sehr sehr freuen ;)
 
jap. Ich kann dir auch sagen, was den ganzen Quatsch langsam macht. Das ist nicht das Replace. Das sind deine beiden ineinander verschachtelten Schleifen. Die machen das System langsam. Versuch dafür eine andere Lösung zu finden. ;)
 
Ich kenn mich jetzt mit xml nicht aus ... Muss jeder Tag geschlossen werden, oder nur <hr>; <br>; <img>; <input> ?
 
Hallo.

In XML müssen alle Tags geschlossen werden. Dabei gibt es zwei Varianten:

HTML:
<b>Fetter Text/b>

und die Andere:

HTML:
<br />

Beide Tags gelten als geschlossen. In meinem Fall konzentriere ich mich auf die Tags im zweiten Beispiel (also br, hr, input, img).

Gruß
 
Versuchs mal hiermit:

PHP:
preg_replace('|<(.*[^/])>|sU','<$1 />',$html);

Hier wird jetzt jedes <Tag> durch <Tag /> ersetzt. Ich weiß jetzt nicht genau ob du das so wolltest, wenn nicht kann man das auch noch anpassen.
Da ich auch nicht wirklich der RegEx-Profi bin, weiß ich auch nicht ob die Lösung so sauber ist, sie funktioniert jedenfalls, aber das hatt ja oft nix zu bedeuten.
 
Zuletzt bearbeitet:
Zurück