やりたいこと
/foo をリクエストされたら http://example.com/?q=%26 へリダイレクトしたい。
%26 は & をURLエンコードしたものなので、 q の値として & という1文字を渡すというだけのURLです。
%1, %2, … が後方参照用の変数と解釈される罠
まず最初は単純に以下のような RewriteRule を書くと思う。
RewriteRule ^/foo http://example.com/?q=%26 [R,L]
これは期待通りに動いてくれない。
実際に /foo にアクセスしてみると http://example.com/?q=6 というURLに飛ばされます。
何故か? RewriteRule では直前の RewriteCond で正規表現を利用した際にマッチしたグループを %1, %2, %3... という形で後方参照できるという機能がある為です。
つまり %2 の部分が後方参照用の変数と解釈されて、しかし直前で RewriteCond は使っていないので %2 は空となっており、結果として %26 の部分が (空文字) + 6 つまり 6 になってしまったわけです。
後方参照用の変数と解釈されないためには % を全て \% に書きなおしてやれば、そのまま % という1文字として解釈してくれることになっています。
勝手にURLエンコードされる罠
後方参照の罠を抜けるために以下のように書き直しました。
RewriteRule ^/foo http://example.com/?q=\%26 [R,L]
しかしこれも期待通りに動いてくれません。
実際に /foo にアクセスしてみると http://example.com/?q=%2526 というURLに飛ばされます。
何故か? RewriteRule ではリダイレクト先URLにクエリが付いていてかつその値にURLエンコードすべき文字が含まれていると勝手にURLエンコードしてくれるという(邪魔な)機能がある為です。
つまり % の部分がURLエンコードされた結果 %25 に置換され、結果として %26 は %2526 になってしまったわけです。
この勝手にURLエンコードされる仕様を回避するには NE または noescape というフラグを付けてやればよい事になっています。
完成形
これでようやく期待通りのリダイレクトが出来ました。
RewriteRule ^/foo http://example.com/?q=\%26 [R,L,NE]
おわり。