【mod_rewrite】正規表現
mod_rewriteでよく使用する正規表現をまとめています。
スポンサードリンク
正規表現
テキスト | |
---|---|
. | 任意の1文字 |
[文字] | いずれかの1文字
【例】 |
[^文字] | これら以外の1文字
【例】 |
文字列1|文字列2 | 文字列1もしくは文字列2 |
量指定子 | |
? | 0回または1回の出現 |
* | 0回以上の繰り返し |
+ | 1回以上の繰り返し |
{n} |
n回の繰り返し 【例】 |
{n,m} |
n回以上、m回以下の繰り返し 【例】 |
{n,} | n回以上の繰り返し |
その他 | |
(文字列) |
グループ化(選択肢の境界を明示したり、後方参照のために使用する) 【例】 |
^ | 行頭(文字位置の指定) |
$ | 行末(文字位置の指定) |
\文字 | 特殊文字をエスケープ(特殊な意味を打ち消して、通常の文字として扱う)
【例】 URLのドット「.」は任意の1文字を表現する正規表現「.」となってしまうので、「ysklog\.net」のようにエスケープ処理する |
- | 置換を禁止する(URL のマッチングだけを行い、置換は行わない)。アクセス禁止の時などに使用する。 また、「C」フラグとともに使用することで、置換をせずに複数のパターンを適用することができる。 |
! | パターンを否定する否定文字(パターンの前に用いる) |
正規表現の使用例
上記の正規表現を利用すればmod_rewriteでの複雑なURL書き換えが可能になります。
ここでは正規表現の使用例を紹介したいと思います。
環境
正規表現の使用例を紹介する前に、環境を定義しておきます。
- ドメイン
○○○.com - ルートディレクトリ
/var/www/html/○○○/ - ルートディレクトリに「abc」ディレクトリと「def」ディレクトリを設置
/var/www/html/○○○/abc/
/var/www/html/○○○/def/ - それらのディレクトリに各種ファイルを作成
「http://○○○.com/abc/hoge.html」でアクセスがあった場合、「/var/www/html/○○○/abc/hoge.html」が出力されます。
エスケープ処理
以下の記述を見て欲しいのですが、ドット「.」の前にエスケープ処理する「\」があることがわかります。
RewriteCond %{HTTP_REFERER} ^http(s)?://(www\.)?ysklog\.net
これは、正規表現の「.」とURLの「.(ドット)」を区別するためのエスケープ処理です。
0回または1回の出現
「○○○.com」からのアクセスを特別に処理させたい場合、RewriteCondはこのように記述します。
RewriteCond %{HTTP_REFERER} ^http(s)?://(www\.)?○○○\.com
これは次のようなことがあるからです。
- 「http://○○○.com」でアクセスした場合、「%{HTTP_REFERER}」は「http://○○○.com」となります。
- 「http://www.○○○.com」でアクセスした場合、「%{HTTP_REFERER}」は「http://www.○○○.com」となります。
- 「https://○○○.com」でアクセスした場合、「%{HTTP_REFERER}」は「https://○○○.com」となります。
このように、サブドメインのありなし、暗号化通信(https)のありなしで「%{HTTP_REFERER}」に渡るものが異なるので
「(」と「)」でグループ化を行い、その0回または1回の出現を指定する「?」が必要となります。
行頭を意味する「^」の使用ミスについて
例えばルートディレクトリに以下を記述した「.htaccess」を記述したとします。
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^ysklog\.net
RewriteRule ^(.*)$ http://www.google.co.jp/ [R=301,L]
このとき、「http://ysklog.net/server/1392.html」からアクセスすると、一見「http://www.google.co.jp/」に301リダイレクトされそうですが、これは実行されません。
なぜなら、「http://ysklog.net/server/1392.html」からのアクセスであった場合、「%{HTTP_REFERER}」は「http://ysklog.net/server/1392.html」となります。
これは「^ysklog\.net」とマッチしません。なぜなら先頭を指定する「^」のあとに「ysklog\.net」が続いているからです。
この場合、次のようにしなければなりません。
RewriteCond %{HTTP_REFERER} ^http(s)?://(www\.)?ysklog\.net
(.*)について
「(.*)」は最もよく使われる正規表現パターンです。
RewriteEngine On
RewriteRule ^(.*)$ abc/$1
例えば「http://○○○.com/hoge.html」にアクセスがあった場合、RewriteRuleのパターン部分には「hoge.html」が渡ります。
「^」は行頭、「$」は行末を表しますが、「.*」はあらゆる文字列を表現できるので「^(.*)$」と「hoge.html」はマッチします。
このとき「(」と「)」の間はグループ化されており、「(.*)」は「hoge.html」となり、後方参照されます(つまり「$1」の部分が「hoge.html」となる)。
そのため「abc/$1」は「abc/hoge.html」となり、
「http://○○○.com/hoge.html」にアクセスがあった場合、「/var/www/html/○○○/abc/hoge.html」のファイルが出力されるようになります。
後方参照について
上で後方参照という言葉が出てきましたが、言葉での説明は難しいのでもう一つ例を出したいと思います。
RewriteEngine On
RewriteRule ^.*/(.*)$ def/$1
例えば「http://○○○.com/abc/hoge.html」にアクセスがあった場合、RewriteRuleのパターン部分には「abc/hoge.html」が渡ります。
「.*」は「abc」の部分、「(.*)」は「hoge.html」の部分に対応します。
このとき「(.*)」はグループ化されており、後方参照されます。つまり「def/$1」の部分が「def/hoge.html」となります。
すなわち、「http://○○○.com/abc/hoge.html」にアクセスがあった場合、「/var/www/html/○○○/def/hoge.html」のファイルが出力されます。
※一つ目の「.*」は「()」で囲まれていません。二つ目の「.*」は「()」で囲まれているので、後方の「$1」にはこれが代入されます。
orを意味する「|」でコンパクトに表記する
RewriteEngine On
RewriteRule ^(.*)\.html$ test/$1
RewriteRule ^(.*)\.jpg$ test/$1
これは、正規表現を使うと次のようにコンパクトにすることができます。
RewriteEngine On
RewriteRule ^(.*)\.(html|jpg)$ test/$1.$2
数字の正規表現
RewriteEngine On
RewriteRule ^20[0-9][0-9]\.html$ test/hoge.html
「[0-9]」は、0~9のいずれかの数字を表します。
すなわち、「20[0-9][0-9]」は2000~2099の数字(文字列)を表現しています。
また、上は次のようにもできます。
RewriteEngine On
RewriteRule ^20[0-9]{2}\.html$ test/hoge.html
{2}は、直前の表現を2回繰り返すことを表しています。
Warning: count(): Parameter must be an array or an object that implements Countable in /home/yskymk/www/000web/ysklog/mod-rewrite/wp-includes/class-wp-comment-query.php on line 405
1:名無しさん:2020/12/09 20:51:32
この記事でようやく理解できました。半日かかりました・・・