preg_replace Double Spaces to tab (\t) at the begi

2019-07-15 09:17发布

Just a Simple Quick Question. I want to replace the Double Spaces at the begenning of the line by Tabs. Currently I am trying with preg_replace('~^( {2})~', "\t", $text) but that replaces only the first occurrence of Double Space.

--EDIT--

preg_replace('~PATTERN~', "REPLACEMENT", "      HalloWorld")
//Should be equal to "\t\t\tHallo World"

6条回答
唯我独甜
2楼-- · 2019-07-15 09:28

From another questions answer: https://stackoverflow.com/a/4349514/778669

If it is for XML from a DOMDocument which uses 2 spaces to indent:

$var = '<?xml version="1.0" encoding="UTF-8"?>
<root>
  <node>
    <anothernode>some    text</anothernode>
  </node>
</root>';

echo preg_replace_callback('/^( +)</m', function($a) { 
  return str_repeat("\t",intval(strlen($a[1]) / 2)).'<';  
}, $var);

Will replace every double space indent at the start of the line with a tab.

So the result would be (substituting X for tab):

$var = '<?xml version="1.0" encoding="UTF-8"?>
<root>
X<node>
XX<anothernode>some    text</anothernode>
X</node>
</root>';

And the double spaces inside the xml will be left intact.

查看更多
迷人小祖宗
3楼-- · 2019-07-15 09:30

If you want to replace more than one occurrence of double-spaces with tabs, try this:

function spaces_to_tabs($m) {
    return str_repeat("\t", strlen($m[1]) / 2);
}

$text = preg_replace_callback('~^((?: {2})+)~', 'spaces_to_tabs', $text);

If your text is multiline, add the m modifier to your regex so it considers ^ as the start boundary after a newline character (for each line in your string):

~^((?: {2})+)~m
查看更多
ら.Afraid
4楼-- · 2019-07-15 09:31

I found a solution without PREG functions.

Let us say we have a $str = " My Text";

I needed an aux variable to store an integer:

$tmp = strlen($str) - strlen(ltrim($t3)); // If ltrim is not ok for you
                                          // You can use preg_replace()
$tmp = str_repeat("\t", $tmp / 2 /* 2 spaces -> 1 tab */) . ltrim($t3);

The PREG function is more elegant, but I'm not sure of how efficient it is

查看更多
贼婆χ
5楼-- · 2019-07-15 09:35

You can use \G escape sequence for that:

$var = '    Hello    World'; //x4 spaces
echo preg_replace("/\G {2}/","\t",$var);

\G marks the location of the end of the previous match (or the beginning of the string for the first match); that way, all matches after the first one try to consume additional two spaces from the character previous match left off.

查看更多
我想做一个坏孩纸
6楼-- · 2019-07-15 09:38

Testing and wortking:

$var = '  Hello World'; //x2 spaces

echo preg_replace("/^ {2}(.*)$/","\t$1",$var);

Edit

Felix has the force with this one!

echo preg_replace('~(?<![^\s]{2})  ~', "\t",$var);
查看更多
SAY GOODBYE
7楼-- · 2019-07-15 09:39

Proper solution

preg_replace('/^ {2}|\G {2}/Sm', "\t", $text)

Replace first 2 spaces on the line ^ {2} and then every two spaces that follow the last successful replacement \G {2}. \G is last replacement and /S is optimized replace as we are going to replace more occurrences at once and /m treat it as multi-line string.

At the end it will ignore all spaces if they are not at the beginning of the line which I understood was the point, right?

查看更多
登录 后发表回答