カテゴリー
PHP

正規表現を理解しよう

この章では正規表現について説明します。
ショッピングサイトでお買い物をする時、電子メールや住所などの個人情報を入力することがありますが、電子メールや郵便番号などが正しく入力されているのかを調べる必要があります。
そのような時に正規表現を使います。
正規表現とは電子メールや郵便番号などの文字の並びをパターン化して、正規表現特有の記号で表現する形式です。
では例を見てみましょう。1正規表現にはメールアドレスなどの文字列が正規表現のパターンに一致するかを調べるためにpreg_match関数が用意されています。
preg_match関数は一致した回数を返すのですが、一回目で一致した時点で一致するかどうかのチェックを止めるので,マッチしたのならば1を、マッチしなかったのならば0を返します。
では例をみてみましょう。
1この例は1の中に正規表現である1と言う文字列が含まれているかどうか調べています。
このように正規表現パターン文字列は1で囲みます。
この例では1の中の1にマッチしているので1を出力します。
例えば、$kensaku の中身を1のように変更した場合には正規表現の1にマッチしません。
また、$kensaku の中身が1と言うように空白が含まれていても、正規表現の1にマッチしません。
このように正規表現というのはチェックする機能を持っています。
電話番号などが正しく入力されているのかを簡単にチェックできますので、とても便利な機能です。

次の例をみてみましょう。1 正規表現において1の中の1は、文字の初めにマッチするかどうかを調べる時に使います。
この例の場合は1は文字の初めにはないので、マッチしません。
1のように1が前にあればマッチします。
1をメタ文字と言います。

次の例をみてみましょう。1 正規表現において1は、文字の終わりにマッチするかどうかを調べる時に使うメタ文字です。
この例の場合は1は文字の終わりにはないので、マッチしません。
1であればマッチします。

次の例をみてみましょう。1 正規表現パターンの初めに1終わりに1を付けると1のみにマッチしますが、この例の場合は$kensakuの中には1が含まれているのでマッチしません。

次の例をみてみましょう。1 「”/sekai[0-9]/”」は1という文字列とsekaiの後の最初の1文字が0から9までの数字のうちどれか1つにマッチするかどうかを調べます。
パターンのなかの1にはマッチさせたい文字列や数字を並べます。
この例では1の後ろの1文字目が0から9までの数字かどうかを調べるので1と書いています。
1は0から9までという意味です。
1を書き換えると1になりますので、以下のように書いても同じ意味です。1 例の場合は「sekai」にはマッチしているので、後は1の中を判定するのですが、1の後の最初の1文字が数字の5なのでマッチします。1 なぜなら、パターンは1であり、1 の後の最初の1文字は数字の5だからです

1 の場合、sekaiの次の文字がnで0から9までの数字ではないのでマッチしません。

次の例をみてみましょう。1 「sekai[0-9]{7}」は1の後ろに0から9までの数字が7桁含まれているかどうかを判定しています。
1の中にはマッチさせたい桁数を3桁なら3、5桁なら5と指定してください。
$kensaku2の中の数字は3桁しかないので、マッチしません。

次の例をみてみましょう。1 「sekai]の後ろの2から9までの数字が2桁以上7桁以下であるか判定しています。
この例では2桁以上なのでマッチしますが1桁の場合はマッチしません。
「{2,7}」の中の左辺は始まりの数字で、右辺は終わりの数字で、始まりの数字以上終わりの数字以下繰り返しているかを判定できます。

次の例をみてみましょう。1 「sekai」の後ろに1が付いていますが、これはメタ文字です。
このメタ文字は任意の1文字にマッチする機能を持っています。
これは数字でも文字でもなんでもマッチします。
この例ではsekaiの後ろの1にマッチしています。
しかしこのメタ文字は改行文字にはマッチしませんので注意してください。

次の例をみてみましょう。1 正規表現の中でドット「.」そのものにマッチさせたい場合は1のようにドットの前に1を入れてください。
「¥」を入れないとメタ文字になってしまいます。
この例ではsekaiの後ろのドットそのものにマッチします。

次の例をみてみましょう。1 「[a-zA-Z0-9_]」は英大文字と英小文字、数字,アンダーバーのどれか1文字にマッチするかどうかを調べる時に使います。
これをメタ文字で表すと1です。
つまり、1と書いても同じ意味です。
この例ではsekaiのうしろのアンダーバーにマッチしています。

次の例をみてみましょう。1  [^0-9]は0から9以外という意味です。
1のカッコのなかで1を使うと1という意味になります。
この例の場合には指定した数字以外の任意の1文字にマッチします。
「^」は、左ブラケットの直後に入れてください。
注意点は[a-z^0-9]というように「^」を先頭ではなくて途中に書くとただ単にキャレットと言う意味になります。
ブラケットを使わないで、1のように1の中で1を使うと文字の初めにマッチする表現になりますので違いに注意してください。
この例の答えは1の次の文字が数字なので1が出力されます。
[^0-9]を別の表現で表すと1になります。
他の例を以下に紹介します。
「/sekai[^abcd]/」と書けば1の次の文字がabcd以外という意味になります。

次の例をみてみましょう。1 「?」(メタ文字)の意味は「?」の直前のものが、あってもいいし、なくてもいい、別の表現で言いますと「?」の直前の物が0個か1個という意味です。
つまり、直前のものが 0 回または1 回出現するものとマッチします。
この例の場合にはeがない状態である1でもマッチしますし、eがある状態である1でもマッチします。
「”/se?kai/”」は1と書き替えても同じ意味になります。
この例では1の中の「e」はあってもなくてもいいのでマッチします。

次の例をみてみましょう。1 「+」(メタ文字)は「+」の直前のものが1個以上マッチするという意味です。
つまり、直前のものが 1 回以上の繰り返しをした時にマッチします。
ですのでこの例は「+」の直前の文字「a」が1 回以上の繰り返しをしていないのでマッチしません。
「”/seka+i/”」は1と同じ意味です。
「x{n,}」の意味は1という意味です。

次の例をみてみましょう。1 「*」(メタ文字)は直前のものに0回以上マッチするのかと言う意味です。
ですので1のように「a」があってもなくてもマッチします。

次の例をみてみましょう。1 「”/(seki)+/”」のようにカッコで囲んでグループ化してそのグループ化したものに対してのパターンを判定します。
このカッコを外すと直前のiだけが対象になりiの1個以上のマッチを判定することになります。
この例の結果は1は1回以上繰り返しているので、1になります。

次の例をみてみましょう。1 (world|japan)の中の「|」は「もしくは」と言う意味で11のどれかが当てはまればマッチします。
英語のorに相当します。
注意点はブランケットの中で1と書いても「もしくは」の意味では使うことが出来ませんので注意してください。

次の例をみてみましょう。1 パターン文字列の右下に「i」が付いていますが、これは修飾子といいます。
これは大文字と小文字を区別しないでマッチングを行います。
例で説明しますと1の先頭が大文字で、正規表現の1の先頭は小文字ですが、「i」があるお蔭で1が出力されます。

次の例をみてみましょう。1 メタ文字「.」は通常は改行文字 にはマッチしませんが,1と言う「修飾子」を付けることによって改行文字を含めてあらゆる文字にマッチさせることが出来ます。
1のようにiとsを両方指定することも出来ます。
1と順番を変えても動作は同じです。

次の例をみてみましょう。1 この例では郵便番号が正しく入力されているかをチェックしています。
つまり、以下のような意味になります。1 結果は1が出力されます。

次の例をみてみましょう。1 この例では正規表現パターンにマッチしたものを取り出す方法について説明します。
もう一度、preg_match関数の構文を見直してみてください。
第三引数に検索結果が代入される配列という引数がありますので、マッチしたものをこの配列に入れます。
配列$rtの1番前にマッチした文字列の全てが入っていますので, 1にはマッチした「320-0906」
が入っています。

次の例をみてみましょう。11 (紙面の都合で$aの中の正規表現を複数行で書いていますが1行で書いてください)
これはメールアドレスの形式が正しいかどうかを調べる正規表現です。
メールアドレスの形式はある程度決まっているので、その形式をパターン化して、正しいかどうかをチェックすることが出来ます。
これまではパターン文字列は1のように直接書いていましたが、この例の場合にはパターン文字列を1のように変数に入れて使用しています。
メールアドレスの正規表現は少し長いですが、少しずつ区切って説明していきます。1 パターン文字列の中にカッコで囲まれている箇所がありますが、この箇所をサブマッチパターンといいます。
サブマッチした箇所は配列の2番目の要素から順に代入されていきます。
配列の1番目の要素にはマッチした文字列全部が代入されます。1 1結果は以下の通りです。1 =>配列の1番目の要素にはマッチした文字列全部が代入されますので、結果は1です。1 =>サブマッチした箇所は配列の前の要素から順に代入されていきますので、二つある中で一番初めの1 のサブマッチパターンにマッチした文字列が1に入っています。
結果は1です。1 =>サブマッチした箇所は配列の前の要素から順に代入されていきますので、二つある中で二番目の1のサブマッチパターンにマッチした文字列が1に入っています。
結果は1です。

preg_matchは1回マッチしたら検索を中止しますが、すべてのマッチングの結果を得たい場合はpreg_match_all関数を使ってください。1 [マッチした結果を入れる配列]は多次元配列(この本では2次元配列を説明しましたが、原理的には3次元、4次元…..も実現できます。
それを総称して多次元配列と言っています)になります。1 では例をみてみましょう。11 (紙面の都合で$aの中の正規表現を複数行で書いていますが1行で書いてください)
ではpreg_match_allについて説明します。
使い方はpreg_matchと同じですが、[マッチした結果を入れる配列]が多次元配列になりますので、結果は以下の通りになります。1 この例は[PREG_PATTERN_ORDERを指定した場合]ですので、連想配列のそれぞれには以下のものが格納されています。
$rt[0][0]にはメールアドレス全体
$rt[1][0]には1番前のサブパターンマッチでマッチした文字列
$rt[2][0] には2番目のサブパターンマッチでマッチした文字
次は[PREG_SET_ORDERを指定した場合]の結果を見てみましょう。11 (紙面の都合で$aの中の正規表現を複数行で書いていますが1行で書いてください)
結果は以下の通りです。1
連想配列のそれぞれには以下のものが格納されています。
PREG_PATTERN_ORDERとの違いを確認してください。
$rt[0][0]にはメールアドレス全体
$rt[0][1]には1番前のサブパターンマッチでマッチした文字列
$rt[0][2] には2番目のサブパターンマッチでマッチした文字列

次は文字列の検索と置換を行う関数について説明します。1 preg_replace関数は正規表現によって文字列の検索と置換を行う関数です。
検索や置換の対象となる文字列に対して正規表現のパターンで検索を行い、別の文字列に置換します。
では例をみてみましょう。1 以下のように正規表現のパターンにマッチした文字列全体が1に入り、そしてカッコで囲まれた1番前のサブマッチパターンにマッチした箇所が1、2番目のカッコが1という順番で参照されます。

対象があれば3番目は14番目は1と続きます。
これを後方参照と言います。このようにマッチした箇所を簡単に取り出せるので便利です。1 つまり、ここでは正規表現パターンに合致した文字列(この例の場合意にはURL)に対してリンクを張っているわけです。
この例では「¥0」 の部分つまりURLを取り出して、以下の箇所でリンクを張っています。1 結果は以下のようにリンクされたURLが出力されます。1111111