在top-voted answer至 this fantastic question ,以下正则表达式用于 preg_replace
调用(来自答案的 auto_version
函数):
'{\\.([^./]+)$}'
这个正则表达式的最终目标是从给定的文件名中提取文件的扩展名。但是,我对为什么这个正则表达式的开头起作用感到困惑。即:
为什么 \\.
匹配方式与 \.
相同在正则表达式中?
前者不应该匹配 (a) 一个文字反斜杠,后跟 (b) 任何字符,而第二个匹配一个文字句点吗? single quoted strings 的规则说明\\
产生文字反斜杠。
考虑这个简单的例子:
$regex1 = '{\.([^./]+)$}'; // Variant 1 (one backslash)
$regex2 = '{\\.([^./]+)$}'; // Variant 2 (two backslashes)
$subject1 = '/css/foobar.css'; // Regular path
$subject2 = '/css/foobar\\.css'; // Literal backslash before period
echo "<pre>\n";
echo "Subject 1: $subject1\n";
echo "Subject 2: $subject2\n\n";
echo "Regex 1: $regex1\n";
echo "Regex 2: $regex2\n\n";
// Test Variant 1
echo preg_replace($regex1, "-test.\$1", $subject1) . "\n";
echo preg_replace($regex1, "-test.\$1", $subject2) . "\n\n";
// Test Variant 2
echo preg_replace($regex2, "-test.\$1", $subject1) . "\n";
echo preg_replace($regex2, "-test.\$1", $subject2) . "\n\n";
echo "</pre>\n";
输出是:
Subject 1: /css/foobar.css
Subject 2: /css/foobar\.css
Regex 1: {\.([^./]+)$} <-- Output matches regex 2
Regex 2: {\.([^./]+)$} <-- Output matches regex 1
/css/foobar-test.css
/css/foobar\-test.css
/css/foobar-test.css
/css/foobar\-test.css
长话短说:为什么要 \\.
在 preg_replace
中产生相同的匹配结果调用 \.
?
最佳答案
考虑正在进行双重转义:PHP 看到 \\.
并说“好的,这真的是 \.
”。然后正则表达式引擎看到 \.
并说“好的,这意味着一个文字点”。
如果您删除第一个反斜杠,PHP 会看到 \.
并说“这是一个反斜杠后跟一个随机字符——不是单引号或反斜杠,如 the spec——所以它仍然是 \.
”。正则表达式引擎再次看到 \.
并给出与上面相同的结果。
关于php - 为什么\\。平等的\。在preg_replace?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14483972/