<?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代码中使用"\\\\"
或'\\\\'
。
答案 0 :(得分:2)
$b='/\\\\/';
php逐字符解析字符串文字(或多或少)。第一个输入符号是正斜杠。结果是结果(解析步骤)中的正斜杠,输入符号(一个字符,/)从输入中取出。
下一个输入符号是反斜杠。它取自输入,检查下一个字符/符号。这也是反斜杠。这是一个有效的组合,因此第二个符号也取自输入,结果是一个黑色斜杠(对于两个输入符号)。
与第三和第四反斜杠相同。
最后一个输入符号(在文字内)是前锋 - &gt;结果中的转发。
- &GT; /\\/
现在对于带有三个反斜杠的字符串:
$a='/\\\/';
php“发现”第一个黑色斜杠,下一个字符是一个黑色斜线 - 这是一个有效的组合,导致结果中出现一个黑色斜杠,输入文字中的两个字符都被取出。
php然后“发现”第三个黑色斜杠,下一个字符是正斜杠,这不是一个有效的组合。所以结果就是一个黑色的片段(因为php喜欢并原谅你......)并且只有一个字符来自输入。
下一个输入字符是正斜杠,导致结果中出现向前闪烁
- &GT; /\\/
=&GT;两个文字都编码相同的字符串。
答案 1 :(得分:2)
有关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
只需要转义两个字符:撇号和反斜杠; /
)的网址,路径或其他字符串时使用#
,~
,!
或@
作为{{ 1}}分隔符(regex
本身没有使用哪个分隔符);这样,在regex
; regex
字符转义; f.e.,短划线(regex
)只有在character classes中使用时才有特殊含义;在它们之外逃脱它是没用的(即使在字符类中,如果它被放置为-
附件中的第一个或最后一个字符,它可以在没有任何特殊含义的情况下使用不引用;