在top-voted answer到this fantastic question,下面的正則表達式是在preg_replace
調用中使用(從答案的auto_version
功能):爲什麼\。平等。在preg_replace?
'{\\.([^./]+)$}'
這個正則表達式的最終目標是從給定的文件名中提取文件的擴展名。然而,我很困惑這個正則表達式的開始爲什麼起作用。即:
爲什麼\\.
在正則表達式中與\.
的匹配方式相同?
不應該前者匹配(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
呼叫作爲\.
相同匹配的結果嗎?
所以如果最終目標是匹配文字反斜槓,我想你必須考慮到可能發生的多層次的轉義?就像'{\\\。}',產生'\\。'? –
@JonahBishop:的確如此。再次,PHP字符串中的三個或四個反斜槓將最終匹配正則表達式中的文字反斜槓(除非有三個後跟一個單引號,但是您會得到該圖片)。 – Jon
這裏的間接級別非常有趣。我明白爲什麼這種事情的測試用例是個好主意。謝謝你的出色答案。 –