Search code examples
phpregexescapingbackslash

Use preg_replace() to add two backslashes before each match


I have code below, what I need to change to get result mercedes\\-benz instead of mercedes\-benz

$value = 'mercedes-benz';
$pattern = '/(\+|-|\/|&&|\|\||!|\(|\)|\{|}|\[|]|\^|"|~|\*|\?|:|\\\)/';
$replace = '\\\\${1}';
echo preg_replace($pattern, $replace, $value);

Solution

  • Welcome to the joys of "leaning toothpick syndrome" - backslash is such a commonly used escape character that it frequently requires escaping multiple times. Let's have a look at your case:

    • Required output (presumably because of some other escaping context): \\
    • Escape each \ with an additional \ for use in the PCRE regex engine: \\\\
    • Escape each \ there for use in a PHP string: \\\\\\\\
    $value = 'mercedes-benz';
    $pattern = '/(\+|-|\/|&&|\|\||!|\(|\)|\{|}|\[|]|\^|"|~|\*|\?|:|\\\)/';
    $replace = '\\\\\\\\${1}';
    echo preg_replace($pattern, $replace, $value);
    

    As mickmackusa points out, you can get away with six rather than eight backslashes in some cases, such as a replacement of '\\\\\\'; this works because the regex engine sees \\\, which is an escaped backslash (\\) followed by a single backslash (\) that can't be escaping anything because it's the end of the string. Simply doubling for each "layer" of escaping is probably safer than learning when this short-cut is and isn't valid, though.