// PHP 5.4.1
// Either three or four \ can be used to match a '\'.
echo preg_match( '/\\\/', '\\' ); // 1
echo preg_match( '/\\\\/', '\\' ); // 1
// Match two backslashes `\\`.
echo preg_match( '/\\\\\\/', '\\\\' ); // Warning: No ending delimiter '/' found
echo preg_match( '/\\\\\\\/', '\\\\' ); // 1
echo preg_match( '/\\\\\\\\/', '\\\\' ); // 1
// Match one backslash using a character class.
echo preg_match( '/[\\]/', '\\' ); // 0
echo preg_match( '/[\\\]/', '\\' ); // 1
echo preg_match( '/[\\\\]/', '\\' ); // 1
When using three backslashes to match a '\' the pattern below is interpreted as match a '\' followed by an 's'.
echo preg_match( '/\\\\s/', '\\ ' ); // 0
echo preg_match( '/\\\\s/', '\\s' ); // 1
When using four backslashes to match a '\' the pattern below is interpreted as match a '\' followed by a space character.
echo preg_match( '/\\\\\s/', '\\ ' ); // 1
echo preg_match( '/\\\\\s/', '\\s' ); // 0
The same applies if inside a character class.
echo preg_match( '/[\\\\s]/', ' ' ); // 0
echo preg_match( '/[\\\\\s]/', ' ' ); // 1
None of the above results are affected by enclosing the strings in double instead of single quotes.
Conclusions:
Whether inside or outside a bracketed character class, a literal backslash can be matched using just three backslashes '\\\' unless the next character in the pattern is also backslashed, in which case the literal backslash must be matched using four backslashes.
Recommendation:
Always use four backslashes '\\\\' in a regex pattern when seeking to match a backslash.
Escape sequences.
Answer from MikeM on Stack Overflow// PHP 5.4.1
// Either three or four \ can be used to match a '\'.
echo preg_match( '/\\\/', '\\' ); // 1
echo preg_match( '/\\\\/', '\\' ); // 1
// Match two backslashes `\\`.
echo preg_match( '/\\\\\\/', '\\\\' ); // Warning: No ending delimiter '/' found
echo preg_match( '/\\\\\\\/', '\\\\' ); // 1
echo preg_match( '/\\\\\\\\/', '\\\\' ); // 1
// Match one backslash using a character class.
echo preg_match( '/[\\]/', '\\' ); // 0
echo preg_match( '/[\\\]/', '\\' ); // 1
echo preg_match( '/[\\\\]/', '\\' ); // 1
When using three backslashes to match a '\' the pattern below is interpreted as match a '\' followed by an 's'.
echo preg_match( '/\\\\s/', '\\ ' ); // 0
echo preg_match( '/\\\\s/', '\\s' ); // 1
When using four backslashes to match a '\' the pattern below is interpreted as match a '\' followed by a space character.
echo preg_match( '/\\\\\s/', '\\ ' ); // 1
echo preg_match( '/\\\\\s/', '\\s' ); // 0
The same applies if inside a character class.
echo preg_match( '/[\\\\s]/', ' ' ); // 0
echo preg_match( '/[\\\\\s]/', ' ' ); // 1
None of the above results are affected by enclosing the strings in double instead of single quotes.
Conclusions:
Whether inside or outside a bracketed character class, a literal backslash can be matched using just three backslashes '\\\' unless the next character in the pattern is also backslashed, in which case the literal backslash must be matched using four backslashes.
Recommendation:
Always use four backslashes '\\\\' in a regex pattern when seeking to match a backslash.
Escape sequences.
To avoid this kind of unclear code you can use \x5c Like this :)
echo preg_replace( '/\x5c\w+\.php
{0}</b>', __FILE__ );
The backslash has a special meaning in both regexen and PHP. In both cases it is used as an escape character. For example, if you want to write a literal quote character inside a PHP string literal, this won't work:
$str = ''';
PHP would get "confused" which ' ends the string and which is part of the string. That's where \ comes in:
$str = '\'';
It escapes the special meaning of ', so instead of terminating the string literal, it is now just a normal character in the string. There are more escape sequences like \n as well.
This now means that \ is a special character with a special meaning. To escape this conundrum when you want to write a literal \, you'll have to escape literal backslashes as \\:
$str = '\\'; // string literal representing one backslash
This works the same in both PHP and regexen. If you want to write a literal backslash in a regex, you have to write /\\/. Now, since you're writing your regexen as PHP strings, you need to double escape them:
$regex = '/\\\\/';
One pair of \\ is first reduced to one \ by the PHP string escaping mechanism, so the actual regex is /\\/, which is a regex which means "one backslash".
I think you can use "preg_quote()":
http://php.net/preg_quote
This function escapes special chars, so you can give an input as it is, without escaping by yourself:
<?php
$string = "online 24/7. Only for \o/";
$escaped_string = preg_quote($string, "/"); // 2nd param is optional and used if you want to escape also the delimiter of your regex
echo $escaped_string; // $escaped_string: "online 24\/7. Only for \\o\/"
?>
Because there are two levels of parsing being done, once by PHP, and a second time by the regular expression engine:
- The intended target:
\ - Well I need to put that in a string without it escaping the character after it:
"\\", PHP sees\ - Now I need to feed that into a regex:
"\\\\"PHP sees\\, regex engine sees\
The function preg_quote() will remove a layer of confusion for you by escaping all regular expression metacharacters for you. eg:
$foo = preg_quote("c:\\some\\path\\or_whatever");
preg_match("/$foo/", $bar);
###edit
You seem to be thinking of this as "units of \\", which doesn't seem like an accurate depiction of what is happening. For a better example let's use a different character that is also significant in both PHP and regular expressions, $.
- Intended target:
$ - Escaping for a PHP string:
"\$", the literal string seen by PHP is$ - Escaping for a PHP string to be interpreted as a literal
$in a regular expression:
"\\\$", PHP sees the literal string\$, the regular expression sees the literal string$
Illustrated with different styles of braces representing different levels of escaping:
0: $ $
1: \$ [\$]
2: \\\\ [{\\}{\$}]
0: \ \
1: \\ [\\]
2: \\\\ [{\\}{\\}]
0: \\server\$c\Windows
1: [\\][\\]server[\\][\$]c[\\]Windows
2: [{\\}{\\}][{\\}{\\}]server[{\\}{\\}][{\\}{\$}]c[{\\}{\\}]Windows
Which also illustrates why dealing with Windows paths sucks butts.
This is because the backslash has a special meaning in both a php string and a regular expression, so you must escape it twice:
To match a single backslash, the pure regex should be:
/\\/
If it was:
/\/
, the backslash would be escaping the forward slash, leading to an invalid regex matching a single forward slash, but missing it's ending slash.
Then, this pure regex is put into a php string, and each backslash is again escaped:
'/\\\\/'
There is a list of special Regex characters in the PHP documentation here: http://php.net/manual/en/function.preg-quote.php
The special regular expression characters are:
. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
Perhaps you will find the preg_quote function useful:
preg_quote() takes str and puts a backslash in front of every character that is part of the regular expression syntax. This is useful if you have a run-time string that you need to match in some text and the string may contain special regex characters.
The special regular expression characters are: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
If you have a string, you will need to escape the backslashes (and quotes) for the string literal. Or, depending on how the function builds the regex from the string, you might not need to escape slashes at all (I don't think so here).
"iframe=-*,src(match=\"/^(http:\\/\\/www\\.youtube\\.com\\/embed\\/)[^\\/\\s\\\\]+$/\")"
In PHP, you can also use a different regex delimiter:
~^(http://www\.youtube\.com/embed/)[^/\s\\\\]+$~