この素晴らしい質問に対する上位投票の回答では、次の正規表現が(回答の関数からの)呼び出しで使用されています。preg_replace
auto_version
'{\\.([^./]+)$}'
この正規表現の最終目標は、指定されたファイル名からファイルの拡張子を抽出することです。ただし、この正規表現の最初の部分が機能する理由については混乱しています。すなわち:
正規表現\\.
と同じように一致するのはなぜですか?\.
前者は(a)1つのリテラルバックスラッシュに一致し、その後に(b)任意の文字が一致し、2番目は1つのリテラルピリオドに一致するべきではありませんか?一重引用符で囲まれた文字列の規則\\
は、文字通りの円記号を生成すると述べています。
この簡単な例を考えてみましょう。
$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
\.