Replacing spaces using regex in PHP

12,298

Solution 1

I'd guess that it would be easier to find each space and replace it. To do that, use "look-ahead" and "look-behind" groups.

Or, find a space (\x20) that is either lead by or followed by any single whitespace (\s); but, only replace the space.

$str = "asdasd asdasd  asdas1\n asda234 4545    54\n  34545 345  34534\n34 345\n";

print preg_replace("/(?<=\s)\x20|\x20(?=\s)/", "&#160;", $str);

(I opted for #160 since markdown parses nbsp.)

Results in:

asdasd asdasd&#160;&#160;asdas1
&#160;asda234 4545&#160;&#160;&#160;&#160;54
&#160;&#160;34545 345&#160;&#160;34534
34 345

For more info, check out PCRE and perlre.


reply to comments

@Sprogz: At first, I thought the same. But the example shows a "\n " => "\n&nbsp;" between the 1st and 2nd lines.

Solution 2

You can use PHP's /e modifier to execute some code in the replacement, like this:

$str = preg_replace('/( {2,}|^ )/em', 'str_repeat("&nbsp;", strlen("\1"))', $str);

I've changed the regular expression to capture the spaces. The /m modifer puts it into multi-line mode, so ^ matches the start of any line.

Share:
12,298
user1798101
Author by

user1798101

Updated on June 04, 2022

Comments

  • user1798101
    user1798101 almost 2 years

    I'm pretty new to regular expressions. I have a requirement to replace spaces in a piece of multi-line text. The replacement rules are these:

    • Replace all spaces at start-of-line with a non-breaking space (&nbsp;).
    • Replace any instance of repeated spaces (more than one space together) with the same number of non-breaking-spaces.
    • Single spaces which are not at start-of-line remain untouched.

    I used the Regex Coach to build the matching pattern:

    /( ){2,}|^( )/
    

    Let's assume I have this input text:

    asdasd asdasd  asdas1
     asda234 4545    54
      34545 345  34534
    34 345
    

    Using a PHP regular expression replace function (like preg_replace()), I want to get this output:

    asdasd asdasd&amp;nbsp;&amp;nbsp;asdas1
    &amp;nbsp;asda234 4545&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;54
    &amp;nbsp;&amp;nbsp;34545 345&amp;nbsp;&amp;nbsp;34534
    34 345
    

    I'm happy doing simple text substitutions using regular expressions, but I'm having trouble working out how to replace multiple-times inside the match in order to get the output I desire.