4

how to replace group of double backslash in a string to *

for example:

\\\\a ->  **a
\\\a  ->  *\a
\\a   ->  *a
\a    ->  \a

I try use both str_replace and preg_replace but it failed at the second case

str_replace('\\', '*', $str);
preg_replace('/\\\\/', '*', $str);

=> `\\\a` -> `**a`

the reason i want to do this is i want something same as Split string by delimiter, but not if it is escaped but

$str = '1|2\|2|3\\|4\\\|4';
$r   = preg_split('~\\\\.(*SKIP)(*FAIL)|\|~s', $str);
var_dump($r);

give me.

  0 => string '1' (length=1)
  1 => string '2\|2' (length=4)
  2 => string '3\|4\\' (length=6)
  3 => string '4' (length=1)

i expect something like

  [0] => 1
  [1] => 2\|2
  [2] => 3\\
  [3] => 4\\\|4

php 5.4.45-2

Community
  • 1
  • 1
Hardy
  • 1,499
  • 2
  • 26
  • 39

1 Answers1

3

A literal backslash in PHP single-quoted strings must be declared with 2 backslashes: to print 1|2\|2|3\\|4\\\|4 you need $str = '1|2\\|2|3\\\\|4\\\\\\|4';.

In a regex, the literal backslash can be matched with 4 backslashes.

Here is an updated PHP code:

$str = '1|2\\|2|3\\\\|4\\\\\\|4';
// echo $str . PHP_EOL; => 1|2\|2|3\\|4\\\|4
$r   = preg_split('~\\\\.(*SKIP)(*FAIL)|\\|~s', $str);
var_dump($r);

Result:

array(4) {
  [0]=>
  string(1) "1"
  [1]=>
  string(4) "2\|2"
  [2]=>
  string(3) "3\\"
  [3]=>
  string(6) "4\\\|4"
}

And to obtain **a from \\a you can thus use

$str = '\\\\a';
$r   = preg_replace('~\\\\~s', '*', $str);

See another demo

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • let say that my original string is `'1|2\|2|3\\|4\\\|4';` how can i convert it to `'1|2\\|2|3\\\\|4\\\\\\|4';` ? – Hardy Nov 02 '15 at 11:19
  • I do not know how you can [tell a `2\|2` from `3\|4`](https://ideone.com/pjTLHG). Even if you convert the string into a byte array with [`$byte_array = unpack('C*', $str);`](https://ideone.com/HLTE1b), you will not find the difference. – Wiktor Stribiżew Nov 02 '15 at 11:23