Break string with line breaks into HTML paragraphs

2019-04-08 07:04发布

问题:

I'm getting text from my MySQL database which is broken into lines (paragraphs). It's stored in the variable $post_data['content']. How do I make it print out with the line breaks?

The code I'm currently using:

$post_data['content'] = explode("\n", $post_data['content']);
$post = "<p>" . implode("</p><p>", array_values($post_data['content'])) . "</p>";

This doesn't work to the extent I want it to.

If I have text like this in the database:

line 1 paragraph 1,
line 2 paragraph 1.

line 3 paragraph 2,
line 4 paragraph 2,
line 5 paragraph 2.

The code would display like this (which I don't want):

<p>line 1 paragraph 1,</p>

<p>line 2 paragraph 1.</p>

<p>line 3 paragraph 2,</p>

<p>line 4 paragraph 2,</p>

<p>line 5 paragraph 2.</p>

I want it to group the paragraphs together if there's no white-space between lines (just one line break). Perhaps something with the array after the explode?

回答1:

First, replace line breaks with <br />:

$post = nl2br($post_data['content']);

Then replace double <br /> with closing and opening paragraph tag (the original line break is maintained by nl2br, so I use a regular expression, that matches all styles of line breaks):

$post = '<p>' . preg_replace('#(<br />[\r\n]+){2}#', '</p><p>', $post) . '</p>';

Note that this is XHTML syntax, if you want to have HTML, change the code as follows:

$post = nl2br($post_data['content'], false);
$post = '<p>' . preg_replace('#(<br>[\r\n]+){2}#', '</p><p>', $post) . '</p>';

Test:

$post_data['content'] = <<<TXT
line 1 paragraph 1,
line 2 paragraph 1.

line 3 paragraph 2,
line 4 paragraph 2,
line 5 paragraph 2.
TXT;

$post = nl2br($post_data['content'], false);
$post = '<p>' . preg_replace('#(<br>[\r\n]+){2}#', "</p>\n\n<p>", $post) . '</p>';

echo $post;

Test Output:

<p>line 1 paragraph 1,<br>
line 2 paragraph 1.</p>

<p>line 3 paragraph 2,<br>
line 4 paragraph 2,<br>
line 5 paragraph 2.</p>


回答2:

Without exploding the string.

$post = "<p>" . nl2br($post_data['content']) . "</p>";


回答3:

You can try

$string = 'line 1 paragraph 1,
line 2 paragraph 1.

line 3 paragraph 2,
line 4 paragraph 2,
line 5 paragraph 2.';

echo implode("\n",array_map(function ($v) {
    return sprintf("<p>%s</p>", $v);
}, array_filter(explode("\n", $string))));


回答4:

Another alternative, using paragraphs and line-breaks:

$post = '';
$paragraphs = explode("\n\n", $post_data['content']);
foreach ($paragraphs as $paragraph) {
    $post .= '<p>' . nl2br($paragraph) . '</p>';
}

This should yield:

paragraph 1 line 1
paragraph 1 line 2

paragraph 2 line 1