在 PHP PCRE 函数中双重转义还是不双重转义?

2023-12-19

我一直在寻找一篇关于何时需要双重转义、何时不需要双重转义的可靠文章,但我找不到任何东西。也许我看起来不够仔细,因为我确信在某个地方有一个解释,但让下一个有这个问题的人很容易找到!

以以下正则表达式模式为例:

/\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 />";

Output:

0

1

1

1

因此,看起来对于引号来说并不重要,但是对于美元符号,正如我所想的那样,需要双重转义。


双引号字符串

当涉及到双引号内的转义时,规则是 PHP 将检查紧跟在反斜杠后面的字符。

如果相邻字符在集合中ntrvef\$"或者如果后面有一个数值(规则可以找到here http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.double)它分别被评估为相应的控制字符或序数(十六进制或八进制)表示形式。

需要注意的是,如果给出了无效的转义序列,则不会计算表达式,并且反斜杠和字符都会保留。这与其他一些语言不同,在其他语言中,无效的转义序列会导致错误。

E.g. "domain\.com"将保持原样。

请注意,变量也会在双引号内扩展,例如"$var"需要转义为"\$var".

单引号字符串

从 PHP 5.1.1 开始,单引号字符串内的任何反斜杠(后跟至少一个字符)都将按原样打印,并且不会替换任何变量。这是迄今为止单引号字符串最方便的功能。

常用表达

对于转义正则表达式,最好将转义留给preg_quote():

$foo = preg_match('/' . preg_quote('mine & yours', '/') . '/', $bar);

这样你就不必担心哪些字符需要转义,因此它非常适合用户输入。

也可以看看:preg_quote http://www.php.net/preg_quote

Update

您添加了此测试:

"/me \$ mine/"

这被评估为"/me $ mine/";但在 PCRE 中$具有特殊含义(它是主题结束锚点)。

"/me \\$ mine/"

这被评估为"/me \$ mine/"因此 PHP 本身的反斜杠被转义了,而$为 PCRE 转义。顺便说一句,这只是偶然发生的。

$var = 'something';

"/me \\$var mine/"

这被评估为"/me \something",所以你需要逃避$ again.

"/me \\\$var mine/"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PHP PCRE 函数中双重转义还是不双重转义? 的相关文章

随机推荐