почему 3 обратных слэша равны 4 обратным слэшам в php?

<?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-коде должны использоваться "\\\\" или '\\\\'.


person oliver    schedule 21.01.2015    source источник
comment
он также основан на разделителях.   -  person Avinash Raj    schedule 21.01.2015


Ответы (2)


$b='/\\\\/';

php анализирует строковый литерал (более или менее) символ за символом. Первый входной символ — косая черта. Результатом является прямая косая черта в результате (этапа синтаксического анализа), а входной символ (один символ, /) удаляется из ввода.
Следующий входной символ — обратная косая черта. Он берется из ввода и проверяется следующий символ/символ. Это тоже обратная косая черта. Это допустимая комбинация, поэтому второй символ также берется из ввода, и в результате получается одна черная косая черта (для обоих входных символов).
То же самое с третьим и четвертым обратным слэшем.
Последний введенный символ (в пределах литерал) — это косая черта -> косая черта в результате.
-> /\\/

Теперь для строки с тремя обратными косыми чертами:

$a='/\\\/';

php «находит» первую черную косую черту, следующий символ — черную косую черту — это допустимая комбинация, в результате которой в результате получается одна черная косая черта, а во входном литерале используются оба символа. php затем «находит» третий черный слэш, следующий символ — прямой слэш, это недопустимая комбинация. Таким образом, в результате получается одна черная косая черта (потому что php любит и прощает вас....) и только один символ, взятый из ввода. Следующим входным символом является косая черта, в результате чего в результате получается косая черта.
-> /\\/

=> оба литерала кодируют одну и ту же строку.

person VolkerK    schedule 21.01.2015

Это объясняется в документации на странице о Strings:

В разделе Single quoted он говорит:

Самый простой способ указать строку — заключить ее в одинарные кавычки (символ ').

Чтобы указать буквальную одинарную кавычку, закройте ее обратной косой чертой (\). Чтобы указать буквальную обратную косую черту, удвойте ее (\\). Все остальные экземпляры обратной косой черты будут рассматриваться как буквальная обратная косая черта.

Давайте попробуем интерпретировать ваши строки:

$a='/\\\/';

Прямая косая черта (/) не имеет специального значения в строках PHP, они представляют сами себя.
Первая обратная косая черта (\) экранирует вторую обратную косую черту, как объяснено в первом предложении второго абзаца, процитированного выше.
Третье Обратная косая черта обозначается сама по себе, как объяснено в последнем предложении приведенной выше цитаты, потому что за ней не следует апостроф (') или обратная косая черта (\).

В результате переменная $a содержит такую ​​строку: /\\/.

On

$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 она интерпретируется как буквальная обратная косая черта).

Сочетание PHP и регулярных выражений

Есть бесконечные возможности все усложнить. Давайте постараемся сделать их простыми и поместим некоторые рекомендации для regex в PHP:

  • заключите строку regex в апострофы ('), если это возможно; таким образом, для PHP нужно экранировать только два символа: апостроф и обратную косую черту;
  • при анализе URL-адресов, путей или других строк, которые могут содержать косую черту (/), используйте #, ~, ! или @ в качестве разделителя regex (какой из них не используется в самом regex); таким образом, нет необходимости экранировать разделитель, когда он используется внутри regex;
  • не экранируйте regex символами, когда это не нужно; например, тире (-) имеет особое значение только тогда, когда оно используется в классы персонажей; за их пределами его экранирование бесполезно (и даже в классах символов его можно использовать без кавычек без особого смысла, если он помещается как самый первый или самый последний символ внутри корпуса [...]);
person axiac    schedule 21.01.2015
comment
Итак, если я правильно понимаю, то единственная причина избегать обратной косой черты - это если вы хотите использовать ее рядом с одинарной кавычкой? Так это только там, чтобы избежать синтаксического анализа \'Hi в 'Hi ? Потому что в противном случае обратная косая черта все равно будет преобразована в обратную косую черту, верно? - person Adam; 07.06.2020
comment
Как говорится в документации, если вам нужно представить обратную косую черту в строке, вы должны ее избежать. Это правильный путь. Однако синтаксический анализатор прощает ошибки и не сообщает об ошибке, если обратная косая черта вместе со следующим символом не образует допустимую управляющую последовательность. В этом случае он понимает, что обратная косая черта не использовалась как escape-последовательность, но она должна представлять себя. Хотя кажется, что использовать его таким образом безопасно, я не рекомендую это использование (я знаю, что использовал его таким образом в ответе). Другие языки, производные от C, не работают таким образом и сообщают об ошибке или игнорируют обратную косую черту. - person axiac; 07.06.2020