为什么3反斜杠在php中等于4反斜杠?

时间:2015-01-21 08:24:30

标签: php regex backslash

<?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代码中使用"\\\\"'\\\\'

2 个答案:

答案 0 :(得分:2)

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

php逐字符解析字符串文字(或多或少)。第一个输入符号是正斜杠。结果是结果(解析步骤)中的正斜杠,输入符号(一个字符,/)从输入中取出。
下一个输入符号是反斜杠。它取自输入,检查下一个字符/符号。这也是反斜杠。这是一个有效的组合,因此第二个符号也取自输入,结果是一个黑色斜杠(对于两个输入符号)。
与第三和第四反斜杠相同。
最后一个输入符号(在文字内)是前锋 - &gt;结果中的转发。
- &GT; /\\/

现在对于带有三个反斜杠的字符串:

$a='/\\\/';

php“发现”第一个黑色斜杠,下一个字符是一个黑色斜线 - 这是一个有效的组合,导致结果中出现一个黑色斜杠,输入文字中的两个字符都被取出。 php然后“发现”第三个黑色斜杠,下一个字符是正斜杠,这不是一个有效的组合。所以结果就是一个黑色的片段(因为php喜欢并原谅你......)并且只有一个字符来自输入。 下一个输入字符是正斜杠,导致结果中出现向前闪烁 - &GT; /\\/

=&GT;两个文字都编码相同的字符串。

答案 1 :(得分:2)

有关Strings

的页面文档中对此进行了解释

Single quoted部分下面写着:

  

指定字符串的最简单方法是将其用单引号(字符')括起来。

     

要指定文字单引号,请使用反斜杠(\)对其进行转义。要指定文字反斜杠,请将其加倍(\\)。所有其他反斜杠实例都将被视为字面反斜杠。

让我们尝试解释你的字符串:

$a='/\\\/';

正斜杠(/)在PHP字符串中没有特殊含义,它们代表了自己 第一个反斜杠(\)转义第二个反斜杠,如上面引用的第二段第一句中所述。
第三个反斜杠代表自己,正如上面引用的最后一句所解释的那样,因为它后面没有撇号(')或反斜杠(\)。

因此,变量$a包含此字符串:/\\/

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

有两个反斜杠(第二个和第四个)由第一个和第三个反斜杠转义。最终(运行时)字符串与$a/\\/相同。

注意

上面的讨论是关于PHP源代码中的字符串编码。正如您所看到的,总是有多种(正确的)方法来编码相同的字符串。其他选项(除了用单引号或双引号括起来的字符串文字,使用heredocnowdoc语法)是使用常量(例如,对于文字反斜杠)并从片段构建字符串。

例如:

define('BS', '\');       // can also use '\\', the result is the same
$c = '/'.BS.BS.'/';

不使用转义和单个反斜杠。常量BS包含一个文字反斜杠,并且在其内部值需要反斜杠的任何地方都使用它。如果转义需要反斜杠,则使用真正的反斜杠(没有办法使用BS)。

regex中的逃避是另一回事。首先,regex在运行时解析,运行时$a$b$c包含/\\/,无论它们是如何生成的。

然后,在regex中,忽略一个未跟随特殊字符的反斜杠(参见上面的差异,在PHP中它被解释为文字反斜杠)。

结合PHP&amp;正则表达式

让事情复杂化的可能性无穷无尽。让我们试着让它们变得简单,并在regex中为PHP提供一些指导原则:

    如果可能,
  • regex字符串括在撇号(')中;这样,PHP只需要转义两个字符:撇号和反斜杠;
  • 解析可以包含正斜杠(/)的网址,路径或其他字符串时使用#~!@作为{{ 1}}分隔符(regex本身没有使用哪个分隔符);这样,在regex;
  • 中使用分隔符时,无需转义分隔符
  • 当不需要时,不要以regex字符转义; f.e.,短划线(regex)只有在character classes中使用时才有特殊含义;在它们之外逃脱它是没用的(即使在字符类中,如果它被放置为-附件中的第一个或最后一个字符,它可以在没有任何特殊含义的情况下使用不引用;