私はすでにPHPコントローラを作成していますが、URIパターンをPHPクラス::メソッドの組み合わせにマップするBackbone Router風のJSONルートを作成できるように、PHPの動的正規表現を使用したバックボーン型ルータ
{
"/home" : "index.html",
"/podcasts": "podcasts.html",
"/podcasts/:param1/:param2": "SomeClass::someMethod"
}
バックボーンはURLとルートを照合するための正規表現を動的に作成します。私は/^\/podcasts\/([^\/]+)\/([^\/]+)$/
を取得し、私は上記のコードに、/podcasts/:param1/:param2
のようなルートを渡す場合
function _routeToRegExp (route) {
var optionalParam = /\((.*?)\)/g;
var namedParam = /(\(\?)?:\w+/g;
var splatParam = /\*\w+/g;
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
route = route.replace(escapeRegExp, '\\$&')
.replace(optionalParam, '(?:$1)?')
.replace(namedParam, function(match, optional){
return optional ? match : '([^\/]+)';
})
.replace(splatParam, '(.*?)');
return new RegExp('^' + route + '$');
}
:私は、バックボーン・コードに見ていた、と私は、次のコードを(それはビットが変更されています)を抽出しました。私は正確に同じ正規表現を取得するPHP関数を記述しようとしていた。私が試した:
$route = '/podcasts/:param1/:param2';
$a = preg_replace('/[\-{}\[\]+?.,\\\^$|#\s]/', '\\$&', $route); // escapeRegExp
$b = preg_replace('/\((.*?)\)/', '(?:$1)?', $a); // optionalParam
$c = preg_replace('/(\(\?)?:\w+/', '([^\/]+)', $b); // namedParam
$d = preg_replace('/\*\w+/', '(.*?)', $c); // splatParam
$pattern = "/^{$d}$/";
echo "/^\/podcasts\/([^\/]+)\/([^\/]+)$/\n";
echo "{$pattern}\n";
$matches = array();
preg_match_all($pattern, '/podcasts/param1/param2', $matches);
print_r($matches);
私の出力は次のとおりです。
/^\/podcasts\/([^\/]+)\/([^\/]+)$/ // The expected pattern
/^/podcasts/([^\/]+)/([^\/]+)$/ // echo "{$pattern}\n";
Array // print_r($matches);
(
)
なぜ私の正規表現の出力が違うのですか?私は残りのすべてのマッピング処理を扱うことができますが、JavascriptのようにPHPで正確に同じ正規表現を取得する方法はわかりません。助言がありますか?
これはあまりにもイライラしているので、同僚はCLIを使ってその正規表現を返す非常に便利なnodeJs関数を書いてくれました。 PHPでこれを行う方法が見つかったら、私は確かに正しい答えを投稿します。 :) –
簡単な修正:正規表現の区切りには〜を使用します。つまり、/ pattern /ではなく〜pattern〜です。そうすれば、/文字をエスケープする必要はありません。これは正規表現を少し読みやすくします。 – ajshort