我正在寻找一篇关于什么时候需要双重逃逸以及什么时候没有,但我无法找到任何东西的文章.也许我看起来不够努力,因为我确定某处有一个解释,但让我们很容易找到有这个问题的下一个人!
以下面的正则表达式模式为例:
/\n/
/domain\.com/
/myfeet \$ your feet/
Run Code Online (Sandbox Code Playgroud)
没有什么可以突破的吗?好的,让我们在PHP的preg_match函数的上下文中使用这些示例:
$foo = preg_match("/\n/", $bar);
$foo = preg_match("/domain\.com/", $bar);
$foo = preg_match("/myfeet \$ your feet/", $bar);
Run Code Online (Sandbox Code Playgroud)
根据我的理解,带引号的字符串值的上下文中的反斜杠会转义后续字符,并且表达式是通过带引号的字符串值给出的.
以前会不会像下面这样做,这不会导致错误吗?:
$foo = preg_match("/n/", $bar);
$foo = preg_match("/domain.com/", $bar);
$foo = preg_match("/myfeet $ your feet/", $bar);
Run Code Online (Sandbox Code Playgroud)
这不是我想要的吗?那些表达方式与上面的不一样.
难道我不必像这样写双逃生吗?
$foo = preg_match("/\\n/", $bar);
$foo = preg_match("/domain\\.com/", $bar);
$foo = preg_match("/myfeet \\$ your feet/", $bar);
Run Code Online (Sandbox Code Playgroud)
因此,当PHP处理字符串时,它会将反斜杠转义为反斜杠,然后在传递给PCRE解释器时将其保留?
或者PHP只是神奇地知道我想将反斜杠传递给PCRE解释器...我的意思是它是如何知道我不是想\"逃避我想在我的表达中使用的引用?或使用转义报价时只需要双斜线?就此而言,你需要TRIPLE逃避报价吗?\\\"你知道吗,所以报价被转义并留下了双倍?
这个经验法则是什么?
我刚刚用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 />";
Run Code Online (Sandbox Code Playgroud)
输出:
0
1
1
1
Run Code Online (Sandbox Code Playgroud)
因此,它看起来不知何故它对引号并不重要,但对于美元符号,我认为需要双重逃脱.
双引号字符串
当涉及到双引号中的转义时,规则是PHP将在反斜杠之后立即检查字符.
如果相邻字符在集合中ntrvef\$"或者数字值跟随它(规则可以在这里找到),它将分别被评估为相应的控制字符或序数(十六进制或八进制)表示.
重要的是要注意,如果给出了无效的转义序列,则不计算表达式,并且反斜杠和字符都保留.这与其他语言不同,其中无效的转义序列会导致错误.
例如"domain\.com"将保持原样.
请注意,变量也会在双引号内扩展,例如"$var"需要转义为"\$var".
单引号字符串
从PHP 5.1.1开始,单引号字符串中的任何反斜杠(后跟至少一个字符)将按原样打印,也不会替换任何变量.这是迄今为止单引号字符串最方便的特性.
常用表达
对于转义正则表达式,最好将转义转义为preg_quote():
$foo = preg_match('/' . preg_quote('mine & yours', '/') . '/', $bar);
Run Code Online (Sandbox Code Playgroud)
这样您就不必担心需要转义哪些字符,因此它适用于用户输入.
也可以看看: preg_quote
更新
你添加了这个测试:
"/me \$ mine/"
Run Code Online (Sandbox Code Playgroud)
这被评估为"/me $ mine/"; 但在PCRE中它$具有特殊含义(它是一个主题终结锚).
"/me \\$ mine/"
Run Code Online (Sandbox Code Playgroud)
这被评估为"/me \$ mine/",因此反斜杠为PHP本身进行了$转义,而对于PCRE进行了转义.这只能偶然发挥作用.
$var = 'something';
"/me \\$var mine/"
Run Code Online (Sandbox Code Playgroud)
这被评估为"/me \something",所以你需要$再次逃避.
"/me \\\$var mine/"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2440 次 |
| 最近记录: |