php - 在 PHP PCRE 函数中双重转义或不双重转义?

标签 php regex

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

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

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

相关文章:

regex - _@[^@]*@ 在 bash 中

javascript - 用于骰子滚动系统和使用 javascript 捕获的正则表达式

javascript - 数组结果,用于输入自动完成

javascript - 用于提取标签属性的正则表达式

c# - 如何在Windows C#中以多个连续模式插入字符串

php - Cake php,在当前页面设置flash消息而不丢失表单内容

regex - 否定 RE2 语法中字符串开头的单词匹配?

HTML 代码中的 PHP 变量

javascript - 无法使用PHPMailer在本地提交表单

php - 当复选框为真时突出显示行