<?php
$a='/\\\/';
$b='/\\\\/';
var_dump($a);//string '/\\/' (length=4)
var_dump($b);//string '/\\/' (length=4)
var_dump($a===$b);//boolean true
?>
Почему строка с 3 обратными слешами равна строке с 4 обратными слешами в PHP?
И можем ли мы использовать версию с 3 обратными слешами в регулярном выражении?
Ссылка на PHP говорит, что мы должны использовать 4 обратной косой черты.
Замечания:
Строки PHP с одинарными и двойными кавычками имеют особое значение обратной косой черты. Таким образом, если \
должно соответствовать регулярному выражению \\
, затем "\\\\"
или же '\\\\'
должен использоваться в коде PHP.
$b='/\\\\/';
php анализирует строковый литерал (более или менее) посимвольно. Первым символом ввода является косая черта. Результатом является прямой слеш в результате (шага синтаксического анализа), и входной символ (один символ, /) убирается из входного.
Следующий входной символ — это обратный слеш. Он берется из ввода и проверяется следующий символ / символ. Это также обратный слеш. Это допустимая комбинация, поэтому второй символ также берется из входных данных, и в результате получается одна черная черта (для обоих входных символов).
То же самое с третьим и четвертым обратным слешем.
Последний входной символ (внутри литерала) — это прямой слэш -> прямой слэш в результате.
-> /\\/
Теперь для строки с тремя обратными слешами:
$a='/\\\/';
php «находит» первую черную черту, следующий символ — черную черту — это допустимая комбинация, в результате которой в результате получается одна черная черта и оба символа во входном литерале берутся.
Затем php «находит» третий черный слеш, следующий символ — прямой слэш, это недопустимая комбинация. Таким образом, в результате получается один черный слеш (потому что php любит и прощает вас ….) и только один символ, взятый из ввода.
Следующим вводимым символом является косая черта, в результате — прямая черта в результате.
-> /\\/
=> оба литерала кодируют одну и ту же строку.
Это объясняется в документации на странице о Strings
:
Под Single quoted
В разделе говорится:
Самый простой способ указать строку — заключить ее в одинарные кавычки (символ ‘).
Чтобы указать буквальную одинарную кавычку, экранируйте ее обратной косой чертой (\). Чтобы указать буквальный обратный слеш, удвойте его (\\). Все остальные случаи обратной косой черты будут рассматриваться как буквальная обратная косая черта.
Давайте попробуем интерпретировать ваши строки:
$a='/\\\/';
Косые черты (/
) не имеют специального значения в строках PHP, они представляют себя.
Первый обратный слеш (\
) избегает второй обратной косой черты, как объяснено в первом предложении второго абзаца, приведенного выше.
Третий обратный слеш стоит сам за себя, как объяснено в последнем предложении вышеупомянутой цитаты, потому что за ним не следует апостроф ('
) или обратный слеш (\
).
В результате переменная $a
содержит эту строку: /\\/
,
На
$b='/\\\\/';
есть две обратные косые черты (вторая и четвертая), которые экранируются от первой и третьей обратной косой черты. Последняя строка (во время выполнения) такая же, как и для $a
: /\\/
,
Обсуждение выше о кодировании строк в исходном коде PHP. Как видите, всегда существует более одного (правильного) способа кодирования одной и той же строки. Другие параметры (кроме строковых литералов, заключенных в одинарные или двойные кавычки, используя heredoc
или же nowdoc
синтаксис) заключается в использовании констант (например, для буквенных обратных косых черт) и построении строк из частей.
Например:
define('BS', '\'); // can also use '\\', the result is the same
$c = '/'.BS.BS.'/';
не использует экранирования и единственной обратной косой черты. Постоянная BS
содержит буквальную обратную косую черту и используется везде, где обратная косая черта необходима для ее внутренней ценности. Если для выхода требуется обратная косая черта, то используется реальная обратная косая черта (нет способа использовать BS
для этого).
Побег в regex
это другое дело. Во-первых, regex
анализируется во время выполнения и во время выполнения $a
, $b
а также $c
выше содержат /\\/
независимо от того, как они были созданы.
Затем в regex
обратная косая черта, за которой не следует специальный символ, игнорируется (см. разницу выше, в PHP
это интерпретируется как буквальная обратная косая черта).
Есть бесконечные возможности усложнить вещи. Давайте попробуем сохранить их простыми и дать некоторые рекомендации для regex
в PHP
:
regex
строка в апострофах ('
), если это возможно; таким образом, есть только два символа, которые нужно экранировать для PHP
апостроф и обратный слеш;/
) использовать #
, ~
, !
или же @
как regex
разделитель (который не используется в regex
сам); таким образом, нет необходимости избегать разделителя, когда он используется внутри regex
;regex
персонажи, когда это не нужно; например, тире (-
) имеет особое значение только тогда, когда он используется в классы персонажей; вне их бесполезно избегать его (и даже в классах символов его можно использовать без кавычек, не имея никакого особого значения, если он помещен как самый первый или самый последний символ внутри [...]
корпус);