mod_rewrite,RewriteCondのバックリファレンス
先週の13日に書いたエントリで、Ifブロック中ではmod_rewriteのRewriteRuleバックリファレンス($1とか$2とか)が使えないと書きました。
そこで、RewriteCondのバックリファレンス(%1とか%2とかに書き換え中。これがなかなか難敵ですね。今日遭遇した現象はこんなの。
だいいち、正規表現が複雑なんだよ。
えーとですね。具体的にはかけないのでちょっと文字列を変えながら説明します。URIをリライトするんですが、そのルールが条件で書くと結構単純なんですが正規表現にするとまぁなんとも複雑怪奇。
書き換えて欲しいURIはこんな。
これを
に書き換える。
でも単純に書き換えるわけじゃなくて、書き換えてほしくないURIもある。
書き換えてほしくないURIはこんな。
- /hoge/fuga/foo/xxxxx
- /hoge/fuga/foo/xxxx_yyyy
- /hoge/fuga
- /hoge/fuga/
- /hoge/fuga.html
- /hoge/fuga/XXX.html
- /hoge/fuga/XXX/
- /hoge/fuga/XXX
- /hoge/fuga/YYY.html
- /hoge/fuga/YYY/
- /hoge/fuga/YYY
xxxxやyyyは任意なんですが、XXXとYYYは特定の文字列。
暗号だな
でもって、 最初にRewriteCondに書いた文字列はこんな。
RewriteCond %{REQUEST_URI} ^/hoge/fuga(?!(.html|/($|foo|(XXX|YYY)(.html|/)?))) RewriteRule ^/hoge/fuga/(.*) /hoge/fuga/foo/$1
なんだこりゃ。/hoge/fugaに続いて、.htmlがない、/で終わらない、XXX.htmlとかでも終わらないって表現。
自分で書いてなんだけど一週間後には読めなくなってる自信がある。
これをRewriteCondのバックリファレンスで置き換える。/hoge/fugaに続く文字列をキャプチャすればいいので、否定先読み部分を括弧でキャプチャする。
RewriteCond %{REQUEST_URI} ^/hoge/fuga((?!(.html|/($|foo|(XXX|YYY)(.html|/)?)))) RewriteRule ^/hoge/fuga/(.*) /hoge/fuga/foo%1
動かない
残念ながらこれ動きません。RewriteCond部分はちゃんと引っ掛けてくれてRewriteRuleへ誘導してくれますが、意図した部分がキャプチャされない。
"/hoge/fuga/foo/" が 404だぞって言われます。%1が空っぽなんですね。