codeslayer: Reguläre Ausdrücke: Nur außerhalb von HTML-Tags ersetzen

Beitrag lesen

hi Jakob,

mit regular expressions ist das nicht optimal zu lösen, da man mit ihnen nur schlecht verschachteltes Markup wie HTML verarbeiten kann. besser wäre es, eine art HTML-Parser selbst zu schreiben, der zuverlässig erkennen kann, ob man sich gerade innerhalb eines bestimmten Tags (in diesem Fall <a>) befindet. so etwas gibt es bestimmt schon in php, ich habe allerdings gerade keinen Link zu Hand.

Alternativ kannst du, was wohl am einfachsten wäre, vor dem ersetzen mit preg_replace alle <a>'s aus dem string herausnehmen und danach wieder einsetzen. vorraussetzung: valides XHTML, aber das sollte ja eh der fall sein ;P

<?php
    ####### $content ist der zu verarbeitende Text, woher auch immer der kommt
    $content = 'asdas Test dasd <span><a href="">Test</a> Test <a href="">asd Test</a></span>';

$subChar = chr(26); // ASCII substitution character

preg_match_all("@<a[^>]*>(.*?)</a>@", $content, $matches);
    if (!empty($matches[0])) {
        $links = $matches[0];
        $linkPatterns = array();
        for($i=0; $i<sizeof($links); $i++) {
            // why isn't quotemeta escaping the "/" characters?
            $linkPatterns[$i] = "/".preg_replace("///", "\/", quotemeta($links[$i]))."/";
        }
        $content = preg_replace($linkPatterns, $subChar, $content, 1);
    }

####### Hier kommen deine eigenen Ersetzungen hin
    $content = str_replace('Test', 'Test2', $content);

if (!empty($matches[0])) {
        $content = preg_replace(array_fill(0, sizeof($links), "/".$subChar."/"), $links, $content, 1);
    }
?>

Gruß,
Niklas