php - 为什么\\。平等的\。在preg_replace?

标签 php regex

top-voted answerthis 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/

相关文章:

javascript - 两个数值之间的正则表达式

php - PHP中双引号和单引号的正则表达式

php - 在自定义主题 wordpress 上添加下拉菜单

php - 如何使用ffmpeg在多个区域添加水印?

php - 文本搜索 - 突出显示搜索短语

php - 如何将不同部分的用户统计信息存储在数据库(mysql)中?

javascript - 正则表达式 JavaScript : Match consecutive single line comments

regex - 在 R 中,如何使用正则表达式 [ :punct:] in gsub?

python - 用于在 Python 中匹配 URL 的正则表达式

php 中的 html 或 html 中的 php 代码?