I have a string where 2 backslashes must become 3 backslashes. With all the escaping of backslashes, I can't do it and nothing's working.
For example:
aaaaa\\aaaaa
must become aaaaa\\\aaaaa
aaaaa\\\aaaaa
STAYS aaaaa\\\aaaaa
(2 backslashes in a row must not be detected)I managed this, which works in regex101.com:
(\\\\)([^\\])
so in php, it would be:
preg_replace('/(\\\\)([^\\])/', '\\\$2', $bob);
But php gives me this error message:
preg_replace(): Compilation failed: missing terminating ] for character class at offset 10
So I don't know if it's a bug of PHP, but I need another way of doing this and I can't find the solution on google.
Try this regex:
(?<!\x5C)\x5C{2}(?!\x5C)
Backslashes can be a real nightmare here. It's better to use the ASCII code of the backslash right into the regex.
Sample code:
define('THREE_SLASHES', preg_quote('\\\\\\'));
define('RE_TWO_SLASHES_ONLY', '~(?<!\x5c)\x5c{2}(?!\x5c)~');
$test='aaaaa\\\\aaaaa';
echo preg_replace(RE_TWO_SLASHES_ONLY, THREE_SLASHES, $test) . '<br>';
$test='aaaaa\\\\\\aaaaa';
echo preg_replace(RE_TWO_SLASHES_ONLY, THREE_SLASHES, $test) . '<br>';
Output
aaaaa\\\aaaaa
aaaaa\\\aaaaa
You might like to take advantage of preg_quote
here:
$in1 = <<<'EOD'
aaaaa\\aaaaa
EOD;
$in2 = <<<'EOD'
aaaaa\\\aaaaa
EOD;
echo "input 1: $in1";
echo "input 2: $in2";
$q = preg_quote('\\','/');
echo "output 1: " . preg_replace("/(?<!$q)$q$q(?!$q)/", "$q$q$q", $in1);
echo "output 2: " . preg_replace("/(?<!$q)$q$q(?!$q)/", "$q$q$q", $in2);
I used a nowdoc (available since PHP 5.3.0) to define the input string so that it can be seen exactly as it looks. No parsing is done inside a nowdoc.
$q
is now an escaped single backslash that can be used in preg_replace
wherever you wanted to use a literal \
before.
The regular expression uses negative lookbehind (?<!$q)
and negative lookahead (?!$q)
to ensure that the two slashes in the middle aren't preceded or followed by a slash.
Output:
input 1: aaaaa\\aaaaa
input 2: aaaaa\\\aaaaa
output 1: aaaaa\\\aaaaa
output 2: aaaaa\\\aaaaa
preg_quote
is normally used for variables longer than one character, so might be seen as overkill here. Instead of using it, you could define $q = '\\\\';
(two string-escaped backslashes) and that would achieve the same outcome.