почему при поиске обратной косой черты в регулярном выражении вам нужно избегать обратной косой черты 4 раза?
Пример:
$pattern = '/\\\\/';
$string = 'to\m';
preg_match( $pattern, $string, $matches );
echo "<pre>";
print_r($matches);
echo "</pre>";
Возвращает:
Array
(
[0] => \
)
Потому что есть два уровня синтаксического анализа, один из которых выполняется PHP, а второй — механизмом регулярных выражений:
\
"\\"
PHP видит \
"\\\\"
PHP видит \\
Регулярный двигатель видит \
Функция preg_quote()
избавит вас от путаницы, исключив для вас все метасимволы регулярных выражений. например:
$foo = preg_quote("c:\\some\\path\\or_whatever");
preg_match("/$foo/", $bar);
Вы, кажется, думаете об этом как о «единицах \\
«, что не похоже на точное описание того, что происходит. Для лучшего примера давайте используем другой символ, который также важен как в PHP, так и в регулярных выражениях, $
,
$
"\$"
, буквальная строка, видимая PHP $
$
в регулярном выражении:"\\\$"
PHP видит буквальную строку \$
регулярное выражение видит буквальную строку $
Проиллюстрированы разными стилями фигурных скобок, представляющих разные уровни побега:
0: $ $
1: \$ [\$]
2: \\\\ [{\\}{\$}]
0: \ \
1: \\ [\\]
2: \\\\ [{\\}{\\}]
0: \\server\$c\Windows
1: [\\][\\]server[\\][\$]c[\\]Windows
2: [{\\}{\\}][{\\}{\\}]server[{\\}{\\}][{\\}{\$}]c[{\\}{\\}]Windows
Что также показывает, почему работа с путями Windows — отстой.
Это связано с тем, что обратная косая черта имеет особое значение как в строке php, так и в регулярном выражении, поэтому вы должны экранировать ее дважды:
Чтобы соответствовать одному обратному слешу, регулярное выражение должно быть:
/\\/
Если бы это было:
/\/
, обратная косая черта будет экранировать косую черту, что приведет к недопустимому регулярному выражению, совпадающему с одной косой чертой, но пропущенному завершающему.
Затем это чистое регулярное выражение помещается в строку php, и каждый обратный слэш снова экранируется:
'/\\\\/'
Поскольку обратная косая черта — это особый символ, вам нужно дважды его избегать. Так что \\ для первого обратного слеша и \\ для второго.