Новая строка для функции абзаца
У меня есть эта интересная функция, которую я использую для создания новых строк в абзацах. Я использую его вместо функции 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>';
}
Проблема в том, что всякий раз, когда я пытаюсь создать один разрыв строки, он непреднамеренно удаляет первый символ абзаца под ним. Я недостаточно знаком с regex, чтобы понять, что является причиной проблемы.
Ответы
Ответ 1
Проблема заключается в вашем совпадении для разрывов одной строки. Он соответствует последнему символу перед разрывом строки и первым после. Затем вы заменяете матч на <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>';
}
Ответ 2
Вот еще один подход, который не использует регулярные выражения. Обратите внимание: эта функция удалит любые разрывы строк.
function nl2p($string)
{
$paragraphs = '';
foreach (explode("\n", $string) as $line) {
if (trim($line)) {
$paragraphs .= '<p>' . $line . '</p>';
}
}
return $paragraphs;
}
Если вам нужно сделать это только один раз в своем приложении и не хотите создавать функцию, ее можно легко сделать inline:
<?php foreach (explode("\n", $string) as $line): ?>
<?php if (trim($line)): ?>
<p><?=$line?></p>
<?php endif ?>
<?php endforeach ?>
Ответ 3
Я также написал очень простую версию:
function nl2p($text)
{
return '<p>'.str_replace(array("\r\n", "\r", "\n"), '</p><p>', $text).'</p>';
}
Ответ 4
Ответ @Laurent не работал для меня - оператор else
делал то, что должен был делать оператор $line_breaks == true
, и делал многократные разрывы строк в тегах <br>
, что уже делает нативный PHP nl2br()
.
Вот что мне удалось заставить работать с ожидаемым поведением:
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;
}
Ответ 5
Здесь подход, который приходит с обратным методом для замены абзацев назад на регулярные разрывы строк и наоборот.
Они полезны при создании ввода формы. При сохранении ввода пользователя вы можете конвертировать разрывы строк в теги абзацев, однако при редактировании текста в форме вам может не понадобиться видеть какие-либо символы 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;
}
Ответ 6
Расширение решения @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/>
Ответ 7
Просто введите это между строками:
echo '<br>';
Это даст вам новую строку.