为什么 php 中的 3 个反斜杠等于 4 个反斜杠?
why 3 backslash equal 4 backslash in php?
<?php
$a='/\\/';
$b='/\\/';
var_dump($a);//string '/\/' (length=4)
var_dump($b);//string '/\/' (length=4)
var_dump($a===$b);//boolean true
?>
为什么3个反斜杠的字符串和PHP中4个反斜杠的字符串相等?
我们可以在正则表达式中使用 3 个反斜杠版本吗?
PHP reference 说我们必须使用 4 个反斜杠。
注意:
单引号和双引号 PHP 字符串具有反斜杠的特殊含义。因此,如果 \
必须与正则表达式 \
匹配,则必须在 PHP 代码中使用 "\\"
或 '\\'
。
$b='/\\/';
php 逐字符解析字符串文字(或多或少)。第一个输入符号是正斜杠。结果是(解析步骤的)结果中的正斜杠和输入符号(一个字符,/)从输入中取出。
下一个输入符号是反斜杠。它取自输入并检查下一个 character/symbol。这也是一个反斜杠。这是一个有效的组合,因此第二个符号也取自输入,结果是单个黑斜杠(对于两个输入符号)。
第三个和第四个反斜杠相同。
最后一个输入符号(在文字中)是结果中的正斜杠 -> 正斜杠。
-> /\/
现在对于带有三个反斜杠的字符串:
$a='/\\/';
php "finds" 第一个黑斜杠,下一个字符是黑斜杠 - 这是一个有效的组合,导致结果中有一个黑斜杠,输入文字中的两个字符都被采用。
php 然后 "finds" 第三个黑斜杠,下一个字符是正斜杠,这不是有效的组合。所以结果是一个单一的黑斜杠(因为 php 爱你并原谅你....)并且只从输入中取出一个字符。
下一个输入字符是正斜杠,导致结果中出现正斜杠。
-> /\/
=> 两个文字编码相同的字符串。
关于Strings
页面的文档中有说明:
在 Single quoted
部分下它说:
The simplest way to specify a string is to enclose it in single quotes (the character '
).
To specify a literal single quote, escape it with a backslash (\
). To specify a literal backslash, double it (\
). All other instances of backslash will be treated as a literal backslash.
让我们尝试解释您的字符串:
$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
中,它被解释为文字反斜杠)。
结合 PHP 和正则表达式
让事情变得复杂的可能性无穷无尽。让我们尽量保持简单,并在 PHP
:
中为 regex
提供一些指导方针
- 如果可能,将
regex
字符串括在撇号 ('
) 中;这样 PHP
只有两个字符需要转义:撇号和反斜杠;
- 当解析 URL、路径或其他可以包含正斜杠 (
/
) 的字符串时,使用 #
、~
、!
或 @
作为regex
定界符(regex
本身没有使用);这样,当在 regex
; 中使用分隔符时,无需转义分隔符
- 不要在不需要时转义
regex
个字符; f.e.,破折号(-
)只有用在character classes中才有特殊意义;在它们之外,将它转义是没有用的(即使在字符 类 中,如果它被放置在 [...]
外壳内的第一个或最后一个字符,它也可以不加引号使用而没有任何特殊含义);
<?php
$a='/\\/';
$b='/\\/';
var_dump($a);//string '/\/' (length=4)
var_dump($b);//string '/\/' (length=4)
var_dump($a===$b);//boolean true
?>
为什么3个反斜杠的字符串和PHP中4个反斜杠的字符串相等?
我们可以在正则表达式中使用 3 个反斜杠版本吗?
PHP reference 说我们必须使用 4 个反斜杠。
注意:
单引号和双引号 PHP 字符串具有反斜杠的特殊含义。因此,如果 \
必须与正则表达式 \
匹配,则必须在 PHP 代码中使用 "\\"
或 '\\'
。
$b='/\\/';
php 逐字符解析字符串文字(或多或少)。第一个输入符号是正斜杠。结果是(解析步骤的)结果中的正斜杠和输入符号(一个字符,/)从输入中取出。
下一个输入符号是反斜杠。它取自输入并检查下一个 character/symbol。这也是一个反斜杠。这是一个有效的组合,因此第二个符号也取自输入,结果是单个黑斜杠(对于两个输入符号)。
第三个和第四个反斜杠相同。
最后一个输入符号(在文字中)是结果中的正斜杠 -> 正斜杠。
-> /\/
现在对于带有三个反斜杠的字符串:
$a='/\\/';
php "finds" 第一个黑斜杠,下一个字符是黑斜杠 - 这是一个有效的组合,导致结果中有一个黑斜杠,输入文字中的两个字符都被采用。
php 然后 "finds" 第三个黑斜杠,下一个字符是正斜杠,这不是有效的组合。所以结果是一个单一的黑斜杠(因为 php 爱你并原谅你....)并且只从输入中取出一个字符。
下一个输入字符是正斜杠,导致结果中出现正斜杠。
-> /\/
=> 两个文字编码相同的字符串。
关于Strings
页面的文档中有说明:
在 Single quoted
部分下它说:
The simplest way to specify a string is to enclose it in single quotes (the character
'
).To specify a literal single quote, escape it with a backslash (
\
). To specify a literal backslash, double it (\
). All other instances of backslash will be treated as a literal backslash.
让我们尝试解释您的字符串:
$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
中,它被解释为文字反斜杠)。
结合 PHP 和正则表达式
让事情变得复杂的可能性无穷无尽。让我们尽量保持简单,并在 PHP
:
regex
提供一些指导方针
- 如果可能,将
regex
字符串括在撇号 ('
) 中;这样PHP
只有两个字符需要转义:撇号和反斜杠; - 当解析 URL、路径或其他可以包含正斜杠 (
/
) 的字符串时,使用#
、~
、!
或@
作为regex
定界符(regex
本身没有使用);这样,当在regex
; 中使用分隔符时,无需转义分隔符
- 不要在不需要时转义
regex
个字符; f.e.,破折号(-
)只有用在character classes中才有特殊意义;在它们之外,将它转义是没有用的(即使在字符 类 中,如果它被放置在[...]
外壳内的第一个或最后一个字符,它也可以不加引号使用而没有任何特殊含义);