我一直在寻找一篇关于何时需要双重转义和何时不需要的可靠文章,但我找不到任何东西。也许我看起来不够仔细,因为我确信那里有解释,但让下一个有这个问题的人很容易找到它!
以以下正则表达式模式为例:
/\n/
/domain\.com/
/myfeet \$ your feet/
没什么突破性的吧?好的,让我们在 PHP 的 preg_match 函数的上下文中使用这些示例:
$foo = preg_match("/\n/", $bar);
$foo = preg_match("/domain\.com/", $bar);
$foo = preg_match("/myfeet \$ your feet/", $bar);
据我了解,带引号的字符串值上下文中的反斜杠会转义后面的字符,并且表达式是通过带引号的字符串值给出的。
前一个会不会像做下面的那样,这不会导致错误吗?:
$foo = preg_match("/n/", $bar);
$foo = preg_match("/domain.com/", $bar);
$foo = preg_match("/myfeet $ your feet/", $bar);
哪个不是我想要的?这些表达式与上面的不同。
我不必像这样写他们双重转义吗?
$foo = preg_match("/\\n/", $bar);
$foo = preg_match("/domain\\.com/", $bar);
$foo = preg_match("/myfeet \\$ your feet/", $bar);
因此,当 PHP 处理字符串时,它会将反斜杠转义为一个反斜杠,然后在将其传递给 PCRE 解释器时保留该反斜杠?
或者 PHP 是否神奇地知道我想将反斜杠传递给 PCRE 解释器...我的意思是它怎么知道我不是在尝试 \"
转义我想要的引号在我的表达式中使用?还是在使用转义引号时只需要双斜杠?就此而言,您需要对引号进行三重转义吗?\\\"
你知道,这样引号被转义并留下一个双倍?
这有什么经验法则?
我刚刚用 PHP 做了一个测试:
$bar = "asdfasdf a\"ONE\"sfda dsf adsf me & mine adsf asdf asfd ";
echo preg_match("/me \$ mine/", $bar);
echo "<br /><br />";
echo preg_match("/me \\$ mine/", $bar);
echo "<br /><br />";
echo preg_match("/a\"ONE\"/", $bar);
echo "<br /><br />";
echo preg_match("/a\\\"ONE\\\"/", $bar);
echo "<br /><br />";
输出:
0
1
1
1
所以,它看起来在某种程度上对引号并不重要,但对于美元符号,我认为需要双重转义。
最佳答案
双引号字符串
当谈到在双引号内转义时,规则是 PHP 将检查紧跟在反斜杠后面的字符。
如果相邻字符在集合 ntrvef\$"
中或者它后面有一个数值(可以找到规则 here ),它会被评估为相应的控制字符或序数(十六进制)或八进制)表示,分别。
重要的是要注意,如果给出了无效的转义序列,则不会计算表达式并且反斜杠和字符都会保留。这与其他一些语言不同,在其他一些语言中,无效的转义序列会导致错误。
例如"domain\.com"
将保持原样。
请注意,变量也会在双引号内扩展,例如"$var"
需要转义为"\$var"
。
单引号字符串
自 PHP 5.1.1 起,单引号字符串中的任何反斜杠(并且后跟至少一个字符)将按原样打印,并且不会替换任何变量。这是迄今为止单引号字符串最方便的功能。
正则表达式
对于转义正则表达式,最好将转义留给 preg_quote()
:
$foo = preg_match('/' . preg_quote('mine & yours', '/') . '/', $bar);
这样您就不必担心哪些字符需要转义,因此它适用于用户输入。
另请参阅:preg_quote
更新
你添加了这个测试:
"/me \$ mine/"
这被评估为 "/me $ mine/"
;但在 PCRE 中,$
具有特殊含义(它是主题结尾的 anchor )。
"/me \\$ mine/"
这被评估为 "/me\$ mine/"
因此反斜杠为 PHP 本身转义,而 $
为 PCRE 转义。顺便说一句,这只是偶然的。
$var = 'something';
"/me \\$var mine/"
这被评估为 "/me\something"
,因此您需要再次转义 $
。
"/me \\\$var mine/"
关于php - 在 PHP PCRE 函数中双重转义或不双重转义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14783370/