スポンサードリンク

【mod_rewrite】正規表現

mod_rewriteでよく使用する正規表現をまとめています。

スポンサードリンク

正規表現

テキスト
. 任意の1文字
[文字] いずれかの1文字

【例】
[abe]ではa,b,cいずれかの1文字を意味する
[a-z]では、aからzすなわちアルファベットの小文字1文字を意味する
[-A-Z]では、「-」という文字もしくはアルファベットの大文字1文字を意味する
[-0-9a-zA-Z]では、「-」という文字、0から9、アルファベットの小文字・大文字いずれか1文字を意味する

[^文字] これら以外の1文字

【例】
[^abcd]では、a,b,c,d以外の1文字を意味する
[^0-9]では、数字以外の1文字を意味する

文字列1|文字列2 文字列1もしくは文字列2
量指定子
? 0回または1回の出現
* 0回以上の繰り返し
+ 1回以上の繰り返し
{n}

n回の繰り返し

【例】
[0-9]{4}は、0000~9999までの数字(文字列)を意味する

{n,m}

n回以上、m回以下の繰り返し

【例】
[0-9]{1,4}は、0~9999までの数字を意味する

{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

この記事でようやく理解できました。半日かかりました・・・

コメントフォーム
お名前
コメント