Jeff Puckett II Jeff Puckett II - 2 months ago 9
PHP Question

How to replace spaces with tabs only on a newline?

I have some multi-line strings that are indented with spaces that I would like to convert to tabs.

Take this script for

example.php


<?php

echo <<<EOT
-----------------------------------------------------------------------
Example with spaces:
-----------------------------------------------------------------------

EOT;
$spaces = <<<EOD
For every new line, replace 2 spaces with 1 tab.
Here 2 spaces should start with 1 tab.
Ignore all spaces that don't begin on a new line.
Now 4 spaces will be 2 tabs.
This line starts with only 1 space, so it should remain unchanged.
And 6 spaces will be 3 tabs.
Still skipping all spaces that don't begin on a new line.

EOD;
echo $spaces;

$tabs = <<<EOD
-----------------------------------------------------------------------
Example replaced with tabs:
-----------------------------------------------------------------------
For every new line, replace 2 spaces with 1 tab.
\tHere 2 spaces should start with 1 tab.
Ignore all spaces that don't begin on a new line.
\t\tNow 4 spaces will be 2 tabs.
This line starts with only 1 space, so it should remain unchanged.
\t\t\tAnd 6 spaces will be 3 tabs.
Still skipping all spaces that don't begin on a new line.

EOD;
echo $tabs;


My first failed attempt:

str_replace(" ", "\t", $spaces);


This doesn't work because it will replace multi-spaces in the middle of a line with tabs.

My second failed attempt:

preg_replace("/\n(?=[\h]*[\h])/", "\n\t", $spaces);


This doesn't work because it only replaces the first two spaces with a tab.

I feel like I'm looking for some sort of variable number of replacements function, or a contextually conditional replacement, like if you see
x
spaces at the beginning of a line, then replace with
0.5x
tabs.

If you're trying to test this out, then I would suggest running it in a console to write to a file that you can reload in a text editor to view the tabs.

php example.php > temp.txt

Answer

You may use

preg_replace('~(?:^|\G)\h{2}~m', "\t", $spaces)

See the regex demo

Details:

  • (?:^|\G) - the beginning of a line/string (^) or the end of the previous successful match (\G)
  • \h{2} - 2 horizontal whitespaces.

Since the m option is used, ^ will match start of lines, not just the start of string position.

Comments