it-swarm.it

Nuova linea per la funzione di paragrafo

Ho questa interessante funzione che sto usando per creare nuove linee in paragrafi. Lo sto usando al posto della funzione nl2br (), poiché emette un testo formattato migliore. 

function nl2p($string, $line_breaks = true, $xml = true) {

$string = str_replace(array('<p>', '</p>', '<br>', '<br />'), '', $string);

// It is conceivable that people might still want single line-breaks
// without breaking into a new paragraph.
if ($line_breaks == true)
    return '<p>'.preg_replace(array("/([\n]{2,})/i", "/([^>])\n([^<])/i"), array("</p>\n<p>", '<br'.($xml == true ? ' /' : '').'>'), trim($string)).'</p>';
else 
    return '<p>'.preg_replace(
    array("/([\n]{2,})/i", "/([\r\n]{3,})/i","/([^>])\n([^<])/i"),
    array("</p>\n<p>", "</p>\n<p>", '<br'.($xml == true ? ' /' : '').'>'),

    trim($string)).'</p>'; 

}

Il problema è che ogni volta che provo a creare un'interruzione di riga singola, rimuove inavvertitamente il primo carattere del paragrafo sottostante. Non ho familiarità con le espressioni regolari per capire cosa sta causando il problema. 

Ogni aiuto che puoi offrire è molto apprezzato. 

25
Jeremy

Il problema è con la tua corrispondenza per le interruzioni di linea singola. Corrisponde all'ultimo carattere prima dell'interruzione di riga e il primo dopo. Quindi sostituisci la corrispondenza con <br>, quindi perdi anche quei personaggi. Devi tenerli nella sostituzione.

Prova questo:

function nl2p($string, $line_breaks = true, $xml = true) {

$string = str_replace(array('<p>', '</p>', '<br>', '<br />'), '', $string);

// It is conceivable that people might still want single line-breaks
// without breaking into a new paragraph.
if ($line_breaks == true)
    return '<p>'.preg_replace(array("/([\n]{2,})/i", "/([^>])\n([^<])/i"), array("</p>\n<p>", '$1<br'.($xml == true ? ' /' : '').'>$2'), trim($string)).'</p>';
else 
    return '<p>'.preg_replace(
    array("/([\n]{2,})/i", "/([\r\n]{3,})/i","/([^>])\n([^<])/i"),
    array("</p>\n<p>", "</p>\n<p>", '$1<br'.($xml == true ? ' /' : '').'>$2'),

    trim($string)).'</p>'; 
}
40

Ecco un altro approccio che non usa espressioni regolari. Nota, questa funzione rimuoverà ogni singola interruzione di riga.

function nl2p($string)
{
    $paragraphs = '';

    foreach (explode("\n", $string) as $line) {
        if (trim($line)) {
            $paragraphs .= '<p>' . $line . '</p>';
        }
    }

    return $paragraphs;
}

Se hai solo bisogno di farlo una volta nella tua app e non vuoi creare una funzione, può essere fatto facilmente in linea:

<?php foreach (explode("\n", $string) as $line): ?>
    <?php if (trim($line)): ?>
        <p><?=$line?></p>
    <?php endif ?>
<?php endforeach ?>
36
Jonathan

Ho anche scritto una versione molto semplice:

function nl2p($text)
{
    return '<p>'.str_replace(array("\r\n", "\r", "\n"), '</p><p>', $text).'</p>';
}
5

@ La risposta di Laurent non funzionava per me - la dichiarazione else stava facendo quello che l'istruzione $line_breaks == true avrebbe dovuto fare, e stava creando più interruzioni di riga in tag <br>, che già fa nl2br() nativo di PHP.

Ecco cosa sono riuscito a lavorare con il comportamento previsto:

function nl2p( $string, $line_breaks = true, $xml = true ) {

    // Remove current tags to avoid double-wrapping.
    $string = str_replace( array( '<p>', '</p>', '<br>', '<br />' ), '', $string );

    // Default: Use <br> for single line breaks, <p> for multiple line breaks.
    if ( $line_breaks == true ) {
        $string = '<p>' . preg_replace(
            array( "/([\n]{2,})/i", "/([\r\n]{3,})/i", "/([^>])\n([^<])/i" ),
            array( "</p>\n<p>", "</p>\n<p>", '$1<br' . ( $xml == true ? ' /' : '' ) . '>$2' ),
            trim( $string ) ) . '</p>';

    // Use <p> for all line breaks if $line_breaks is set to false.
    } else {
        $string = '<p>' . preg_replace(
            array( "/([\n]{1,})/i", "/([\r]{1,})/i" ),
            "</p>\n<p>",
            trim( $string ) ) . '</p>';
    }

    // Remove empty paragraph tags.
    $string = str_replace( '<p></p>', '', $string );

    // Return string.
    return $string;

}
1
Shoelaced

Ecco un approccio che viene fornito con un metodo inverso per sostituire i paragrafi alle interruzioni di riga regolari e viceversa. 

Questi sono utili da usare quando si costruisce un input di form. Quando si salva un input di un utente, è possibile che si desideri convertire le interruzioni di riga in tag di paragrafo, tuttavia quando si modifica il testo in un modulo, è possibile che l'utente non veda alcun carattere html. Poi sostituiremmo i paragrafi alle interruzioni di riga.

// This function will convert newlines to HTML paragraphs
// without paying attention to HTML tags. Feed it a raw string and it will
// simply return that string sectioned into HTML paragraphs
function nl2p($str) {
    $arr=explode("\n",$str);
    $out='';

    for($i=0;$i<count($arr);$i++) {
        if(strlen(trim($arr[$i]))>0)
            $out.='<p>'.trim($arr[$i]).'</p>';
    }
    return $out;
}

// Return paragraph tags back to line breaks
function p2nl($str)
{
    $str = preg_replace("/<p[^>]*?>/", "", $str);
    $str = str_replace("</p>", "\r\n", $str);
    return $str;
}
1
internet-nico