Функция новой строки в абзаце


У меня есть интересная функция, которую я использую для создания новых строк в абзацы. Я использую его вместо функции nl2br(), так как он выводит лучше отформатированный текст.

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>'; 

}

Проблема в том, что всякий раз, когда я пытаюсь создать один разрыв строки, он непреднамеренно удаляет первый символ абзаца под ним. Я недостаточно знаком с регулярными выражениями, чтобы понять, в чем причина проблемы.

Мы будем очень признательны за любую помощь, которую вы можете предложить.

 24
Author: Jeremy, 2011-09-14

6 answers

Проблема заключается в вашем совпадении для разрывов одной строки. Он соответствует последнему символу перед разрывом строки и первому после. Затем вы заменяете совпадение на <br>, поэтому вы также теряете эти символы. Вам нужно держать их в замене.

Попробуйте это:

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>'; 
}
 39
Author: Laurent le Beau-Martin, 2011-09-13 23:10:00

Вот еще один подход, который не использует регулярные выражения. Обратите внимание, что эта функция удалит любые одиночные разрывы строк.

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

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

    return $paragraphs;
}

Если вам нужно сделать это только один раз в вашем приложении и вы не хотите создавать функцию, это можно легко сделать встроенным:

<?php foreach (explode("\n", $string) as $line): ?>
    <?php if (trim($line)): ?>
        <p><?=$line?></p>
    <?php endif ?>
<?php endforeach ?>
 34
Author: Jonathan, 2014-06-02 12:39:47

Я также написал очень простую версию:

function nl2p($text)
{
    return '<p>'.str_replace(array("\r\n", "\r", "\n"), '</p><p>', $text).'</p>';
}
 4
Author: NaturalBornCamper, 2017-05-18 08:12:35

Вот подход, который поставляется с обратным методом замены абзацев на обычные разрывы строк и наоборот.

Их полезно использовать при построении ввода формы. При сохранении пользовательского ввода вам может потребоваться преобразовать разрывы строк в теги абзацев, однако при редактировании текста в форме вы можете не захотеть, чтобы пользователь видел какие-либо символы html. Затем мы заменили бы абзацы обратно на разрывы строк.

// 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
Author: internet-nico, 2013-12-02 08:46:29

Расширяя решение @Naturalborncamper:

function nl2p( $text, $class = '' ) {
    $string = str_replace( array( "\r\n\r\n", "\n\n" ), '</p><p>', $text);
    $string = str_replace( array( "\r\n", "\n" ), '<br />', $text);
    return '<p' . ( $class ? ' class="' . $class . '"' : '' ) . '>' . $string . '</p>';
}

Это устраняет как двойные разрывы строк, преобразуя их в абзацы, так и однострочные разрывы, преобразуя их в <br />

 -1
Author: MrCarrot, 2018-04-27 12:01:08

Просто введите это между строками:

echo '<br>';

Это даст вам новую строку.

 -2
Author: Silent Helper, 2017-09-17 00:41:04