1.单引号字符串只转义\'和\\,而双引号都转义且替换php变量;运行

<?php
$a = 'hello\\\p';
echo $a ."<br />";

$b = "hello\\\p";
echo $b ."<br />";

$a = 'hello\\p';
echo $a ."<br />";

$b = "hello\\p";
echo $b ."<br />";

结果为

hello\\p
hello\\p
hello\p
hello\p

此时你会发现不论是单引号还是双引号字符串,在对待\\上都是一样的,只处理一次\\并将其转为\,如果只剩下一个\那么只要不和后面字符产生转义则都不转义直接当作一个字符\;看看

<?php
$a = 'hello\\\n';
echo $a ."<br />";

$b = "hello\\\n";
echo $b ."<br />";

结果为

hello\\n
hello\

2.正则对特殊字符都需要转义,运行

<?php
$a = 'abc\\\$';
$b = "abc\\\$";
echo $a . ":" . $b . "<br />";
preg_match('/\\\\/',$a,$match);
var_dump($match);//匹配字符\
preg_match('/\\\\/',$b,$match);
var_dump($match);//匹配字符\
preg_match("/\\\\/",$a,$match);
var_dump($match);//匹配字符\
preg_match("/\\\\/",$b,$match);
var_dump($match);//匹配字符\
echo "<br />";
preg_match('/\\$/',$a,$match);
var_dump($match);//匹配字符$
preg_match('/\\$/',$b,$match);
var_dump($match);//匹配字符$
preg_match("/\\\$/",$a,$match);
var_dump($match);//匹配字符$
preg_match("/\\\$/",$b,$match);
var_dump($match);//匹配字符$
echo "<br />";
preg_match('/\\\\\$/',$a,$match);
var_dump($match);//匹配字符\$
preg_match('/\\\\\$/',$b,$match);
var_dump($match);//匹配字符\$
preg_match("/\\\\\\\$/",$a,$match);
var_dump($match);//匹配字符$
preg_match("/\\\\\\\$/",$b,$match);
var_dump($match);//匹配字符$
?>

结果为

abc\\$:abc\$
array(1) { [0]=> string(1) "\" }

array(1) { [0]=> string(1) "\" }

array(1) { [0]=> string(1) "\" }

array(1) { [0]=> string(1) "\" }
array(1) { [0]=> string(1) "$" }

array(1) { [0]=> string(1) "$" }

array(1) { [0]=> string(1) "$" }

array(1) { [0]=> string(1) "$" }
array(1) { [0]=> string(2) "\$" }

array(1) { [0]=> string(2) "\$" }

array(1) { [0]=> string(2) "\$" }

array(1) { [0]=> string(2) "\$" }

分析:preg_match第一个参数为正则匹配模式,先按单引号字符串或双引号字符串转义,然后对结果再按正则转义一次,结果就比较好理解了,如'/\\\\\$/'被字符串转义后为'\\\$',再被正则转义为'\$';如"/\\\\\\\$/"被字符串转义后为'\\\$',再被正则转义为'\$'.

小结:勤加练习,找出原理才是解决问题的根本!