tk_
tk_

Reputation: 570

PHP preg_replace more spaces only when after specific substring

I would like to ensure a sufficient readability of a multiline string which contains a code snippet. The goal is to replace normal whitespaces with non breaking spaces so the code snippet is readable in a web browser.

I already replaced all cr+lf with nl2br. But I need to replace all whitespaces that come just after HTML break tag with   No other whitespaces should be touched.

I tried:

$text = nl2br($text);
$text = preg_replace('/(<br \/>)+(\s+)/', '$1&nbsp;', $text); 

but that only replaced one whitespace after HTML break tag.

I want the text (which is result of nl2br):

some text<br />  some other text

become:

some text<br />&nbsp;&nbsp;some other text

How to do that using preg_replace correctly?

Upvotes: 1

Views: 695

Answers (2)

tk_
tk_

Reputation: 570

Correct way is:

    $c_text = str_replace("\r", '', $c_text);
    $c_text = str_replace("\n", '<br />', $c_text);
    $c_text = preg_replace_callback('#<br \/>(\s+)#', function ($match) {
      return '<br />' . str_pad("", strlen($match[1]) * 6, "&nbsp;");
    }, $c_text);                

This makes the texts appear as I wanted. Above solution with pre tag would not work because the code snippets may start at newline even without leading whitespace.

Also keep in mind that nl2br does not replace cr+lf so str_replace is needed as seen in this and previous answer.

You may check the final results at http://tkweb.eu/en/delphicomp/kcontrols.html, the texts are the comments below the article. This web site was made a long time ago and now I just needed a quick improvement of comment readability wo changing them. Because I have no time to make a better system now.

Upvotes: 0

ankhzet
ankhzet

Reputation: 2570

Use preg_replace_callback:

$text = preg_replace_callback('#<br\s*/?>(\s+)#', function ($match) {
    $pad = '';
    $l = strlen($match[1]);
    while ($l-- > 0)
        $pad .= '&nbsp';
    return '<br />' . $pad;
}, $text);`

And with just wrapping in <pre> tag:

$text = "normal text\nother normal text\n some code snippet\n some code snippet\njust another normal text\njust another normal text\n some other code snippet";

$text2 = str_replace("\r", '', $text);

$text2 = preg_replace('#((\n\s+[^\n$]+)+)(\n|$)#', '<pre>[\1]</pre>', $text2);
$text2 = str_replace("\n", '<br />', $text2);

echo "<div>$text2</div>";

Result:

<div>normal text<br />other normal text<pre>[<br /> some code snippet<br /> some code snippet]</pre>just another normal text<br />just another normal text<pre>[<br /> some other code snippet]</pre></div>

...shown as:

normal text
other normal text
[
 some code snippet
 some code snippet]
just another normal text
just another normal text
[
 some other code snippet]

Notice square brackets around "code snippets".

Upvotes: 1

Related Questions