PHPでの抽出方法
正規表現パターンで一致した文字を抽出する方法です。PHPの、preg_match を使用していきます。preg_match 関数では正規表現パターンにマッチする文字が第3引数に配列という形で代入されます。関数の返り値自体は、パターンがあるかないかの診断となります。また、PCRE系では正規表現パターンを表現する場合、/(スラッシュ)でパターンを囲みます。
$str = '〒150-0021 東京都渋谷区'; $pattern = '/[0-9]{3}-[0-9]{4}/'; $match = array(); preg_match($pattern, $str, $match); var_dump($match); array ( 0 => '150-0021', )パターン全体にマッチする文字が インデックス:0に格納されます。また、パターンの一部分を取り出したい場合などがあると思います。この場合、郵便番号の始め3桁と終わり4桁だとした場合、抽出パターンをパーレンで囲みます。こうすることでインデックスが新たに振られデータを格納するようになります。パーレンは抽出対象を明示する他に、正規表現パターンをグループ化する役割も兼ねているので、単純にグループ化だけを行いたい場合は、始まりのパーレン直後に ?: をつけて (?:パターン) のようにすると抽出対象になりません。
$str = '〒160-0000 東京都新宿区'; $pattern = '/([0-9]{3})-([0-9]{4})/'; $match = array(); preg_match($pattern, $str, $match); var_dump($match); array ( 0 => '160-0000', 1 => '160', 2 => '0000', )次は、正規表現パターンに一致した文字を別の文字列に置き換える場合です。正規表現による文字列置換には、preg_replace関数を用います。郵便番号だと置き換える用途が浮かばないので、文中のURLをアンカータグ付きのURLに置き換えてみます。
$str = 'URL: http://www.yahoo.co.jp/ Yahoo! JAPAN'; $pattern = '/http:\/\/[0-9a-z_,.:;&=+*%$#!?@()~\'\/-]+/i'; $replace = '<a href="$0">$0</a>'; $replaced = preg_replace($pattern, $replace, $str); var_dump($replaced); <a href="http://www.yahoo.co.jp/">http://www.yahoo.co.jp/</a> Yahoo! JAPAN置き換え文字列($replace)で、$0 がパターンにマッチした文字(URL)に置き換わってるのがわかると思います。これは後方参照といって、マッチした文字を再び処理の中で用いるための仕組みです。$ と 数字の組み合わせにより、パターンにマッチした文字を参照できます。$0 は正規表現パターン全体にマッチする文字を表しています。もちろん $1、$2、$3 ... というのもあるわけですが、これはパターンの中で、パーレンに囲まれたパターンの文字を表します。
尚、$ を使った後方参照はPHP固有の表現です。他の言語の正規表現で後方参照は \0 を用いています。PHPでも \0 という表記を用いることが出来ますので、上の例を $replace = '<a href="\0">\0</a>'; としても同じ結果が得られます。だだし \0 で困るのが後方参照のすぐ後に数字が続く場合です。1番目のカッコのパターンに '0' を付け加えた文字のつもりで '\10' と書いてしまうと10番目のカッコのパターンと判断されます。こんな場合は $ と大カッコを使って、'${1}0' と書いて、1番目のカッコのパターンに '0' を付け加えた文字を表します。特殊文字のパターンはバックスラッシュでエスケープしてあります。これは、正規表現として評価される前にPHP言語として評価されるための対策です。 TOP
正規表現パターン例
良く使われる正規表現パターンを挙げてみます。ひとつの用途に対していくつものパターンが存在します。また長いパターンもあれば小さなパターンの組み合わせもあります。対象をどう的確に表現するかが肝になります。
・メールアドレス
/^[-._a-zA-Z0-9\/]+@[-._a-z0-9]+\.[a-z]{2,4}$/フォームに入力されたメアドのバリデーションパターンです。RFCで定義されてるメールアドレスの正規表現はとても長いですが、実用的な範囲はこれで足ります。ブランケットの外のドットはバックスラッシュでエスケープします。これにより特殊文字としての意味を省いています。また、ブランケット内の \/ は携帯電話用のメアド用です。他にも、
/^[-.\w\/]+@[-._[:lower:]\d]+\.[[:lower:]]{2,4}$/などがあります。\w は単語を構成するもの(_0-9a-zA-Z)です。\d は数字(Digit)。[:lower:] は文字の集合を表すキャラクタクラスのひとつで a-z を表します。
・URL
/^(?:http|https):\/\/[\w,.:;&=+*%$#!?@()~\'\/-]+$/URLのバリデーションパターンでは、プロトコル先をふたつにマッチするようにしています。ftp もマッチしたい場合は、(?:http|https|ftp) などとします。 また、URLからプロトコル・ドメイン・リクエスト・クエリーを分けて抽出したい場合は以下のようにします。
/(http|https):\/\/([-._a-z\d]+\.[a-z]{2,4})([\w,.:;&=+*%$#!@()~\'\/-]*)\??([\w,.:;&=+*%$#!?@()~\'\/-]*)/
・電話番号
/^0\d{1,4}[-(]?\d{1,4}[-)]?\d{3,4}$/電話番号のバリデーションパターンでは、意外と難しいです。数字とハイフンだけという訳ではなく、固定、携帯、IP電話、フリーダイヤルと桁が異なるので注意が必要です。
・タグ
/<a href="([^"]+)">(.+?)<\/a>/isHTMLファイルからアンカータグのURLを抽出するパターンです。^" でダブルクオートを否定演算にかけています。つまり、ダブルクオートを区切りに間の文字を抽出するパターンとなります。また、(.+?) でリンク文字を引きぬいています。最後のパターン修飾子は i で大文字小文字の区別を無効、s でパターン中のドットを改行を含むという意味になります。
array ( 0 => array ( 0 => '<a href="http://www.yahoo.co.jp/">Yahoo!JAPAN</a>', 1 => 'http://www.yahoo.co.jp/', 2 => 'Yahoo!JAPAN', ), 1 => array ( 0 => '<a href="https://www.google.co.jp/">Google</a>', 1 => 'https://www.google.co.jp/', 2 => 'Google', ), 2 => array ( 0 => '<a href="http://www.bing.com/?cc=jp">Bing</a>', 1 => 'http://www.bing.com/?cc=jp', 2 => 'Bing', ), )TOP
マルチバイト文字の正規表現パターン
正規表現パターンにマルチバイト文字を扱う際は mb_ereg_** 関数を使うことになります。こちらは POSIX系の正規表現です。PCRE系とあきらかに違うところは、パターンを囲む "/" が無いところと、パターン修飾子を引数で指定するところです。その他は処理系ごとにも違うのでその都度確かめてください。マルチバイト文字を扱う際忘れてならないのが文字エンコーディングです。あらかじめ正規表現で扱う文字エンコーディングを mb_regex_encoding 関数で指定します。
・フリガナ
^[ ァ-ヶー]+$文字列が全角カタカナとスペースだけで構成されているパターン。
・ひらがな
^[ ぁ-んー]+$文字列が全角ひらがなとスペースだけで構成されているパターン。"ヴ"や"ヶ" は "ひらがな" にはありません。
・半角カナ
[。-゚]半角カナが含まれているかチェックするパターン。半角カナは濁点や半濁点も1文字なので、検索や並べ替え、文字列を部分的に取り出す場合など、プログラムを複雑にする要因となります。可能ならすべて"全角カナ"に統一を図る方が吉です。
正規表現は結構負荷の高い処理です。乱発はパフォーマンス低下につながります。特定の文字が含まれるか判定するだけなら "strpos" や "strstr" で出来ますし、単純な文字列の置き換えなら "str_replace" や "strtr" で十分です。正規表現が本当に必要か、別の方法はないかよく検討してみましょう。 TOP