BR etiketleri ile satırsonu değiştirin, ama sadece PRE etiketleri içinde

2 Cevap php

Stokta PHP5'ta, bu dönüşümü yapmak için iyi bir preg_replace ifadesi budur:

replace newlines with <br />, ancak <pre> blok içinde

(Feel free to make simplifying assumptions, and ignore corner cases. For example, we can assume that tags will be one line, and not pathological things like )

Giriş metni:

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

Çıktı:

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

(Bağlam motive: Bir wikimedya SyntaxHighlight_GeSHI uzantısı hata 20760 kapatmak için çalışıyor, ve benim PHP becerileri (çoğunlukla Python yapmak) enfiye kadar değildir bulma).

Ben regexen yanı sıra, diğer çözümlere açığım, ama küçük (html ayrıştırma makineleri overkill bina, bir örnek olarak) tercih edilir.

2 Cevap

(Nedense burada görünmüyor) SilentGhost söylediği bir şeye dayanarak:

<?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);
?>

Bu böyle bir şey?

<?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 ) );
}