3 Stimmen

Ersetzen von Zeilenumbrüchen durch BR-Tags, aber nur innerhalb von PRE-Tags

Was ist in PHP5 auf Lager eine gute preg_replace Ausdruck, um diese Umwandlung vorzunehmen:

Zeilenumbrüche ersetzen durch <br /> , aber nur innerhalb <pre> Blöcke

(Es steht Ihnen frei, vereinfachende Annahmen zu treffen, und Eckfälle zu ignorieren. Zum Beispiel können wir annehmen, dass die Tags einzeilig sind und nicht pathologische Dinge wie )

Text eingeben:

<div><pre class='some class'>1
2
3
</pre>
<pre>line 1
line 2
line 3
</pre>
</div>

Sortie :

<div><pre>1<br />2<br />3<br /></pre>
<pre>line 1<br />line 2<br />line 3<br /></pre>
</div>

(Motivierender Kontext: Ich versuche, den Fehler 20760 in einer wikimedia SyntaxHighlight_GeSHI-Erweiterung zu schließen, und stelle fest, dass meine PHP-Kenntnisse (ich mache hauptsächlich Python) nicht ausreichen).

Ich bin offen für andere Lösungen, neben regexen, aber klein ist bevorzugt (als ein Beispiel, Gebäude html parse Maschinerie ist overkill).

6voto

meder omuraliev Punkte 177513

So etwas wie das hier?

<?php

$content = "<div><pre class='some class'>1
2
3
</pre>
<pre>line 1
line 2
line 3
</pre>
</div>
";

function getInnerHTML($Node)
{
     $Body = $Node->ownerDocument->documentElement->firstChild->firstChild;
     $Document = new DOMDocument();    
     $Document->appendChild($Document->importNode($Body,true));
     return $Document->saveHTML();
}

$dom = new DOMDocument();
$dom->loadHTML( $content );
$preElements = $dom->getElementsByTagName('pre');

if ( count( $preElements ) ) {
    foreach ( $preElements as $pre ) {
    $value = preg_replace( '/\n|\r\n/', '<br/>', $pre->nodeValue  );
    $pre->nodeValue = $value;
    }

    echo html_entity_decode( getInnerHTML( $dom->documentElement ) );
}

0voto

Gregg Lind Punkte 19744

Basierend auf einer Aussage von SilentGhost (die aus irgendeinem Grund hier nicht angezeigt wird):

<?php
$str = "<div><pre class='some class' >1
2
3
< / pre>
<pre>line 1
line 2
line 3
</pre>
</div>";

$out = "<div><pre class='some class' >1<br />2<br />3<br />< / pre>
<pre>line 1<br />line 2<br />line 3<br /></pre>
</div>";

function protect_newlines($str) {
    // \n -> <br />, but only if it's in a pre block
    // protects newlines from Parser::doBlockLevels()
    /* split on <pre ... /pre>, basically.  probably good enough */
    $str = " ".$str;  // guarantee split will be in even positions
    //$parts = preg_split('/(<pre .*  pre>)/Umsxu',$str,-1,PREG_SPLIT_DELIM_CAPTURE);
    $parts = preg_split("/(< \s* pre .* \/ \s* pre \s* >)/Umsxu",$str,-1,PREG_SPLIT_DELIM_CAPTURE);
    foreach ($parts as $idx=>$part) {
        if ($idx % 2) {
            $parts[$idx] = preg_replace("/\n/", "<br />", $part);
        }
    }
    $str = implode('',$parts);
    /* chop off the first space, that we had added */
    return substr($str,1);
}

assert(protect_newlines($str) === $out);
?>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X