正規表現とは
正規表現とは、文字列のパターンを正規式で置き換えたものです。英語ではRegular Expressionと言い、プログラム言語やコマンドで標準的に利用されます。特に、パターン検出や抽出・変換を行うコマンドやプログラム言語で用いられます。
正規表現のメリットは、複雑に発生する文字列のパターンマッチングが効率的に行えることにあります。
PHPの正規表現の種類は?
PHPでは正規表現をPCRE形式で表します。PCREとはPerl Compatible Regular Expressionsの略で、Perl5互換の正規表現です。PCREはPerlやPHPの他ApacheやPostfix等でも採用されています。
PHPでは正規表現の構文と種類一覧は以下の通りです。 ・デリミタ パターンをデリミタで囲みます。一般的には'/'(スラッシュ)、'#'(シャープ、ハッシュ)、'~'(チルダ)を用います。その他、英数字・バックスラッシュ・空白文字以外の任意の文字であれば構いませんので、'()'、 '{}'、'[]' 、'<>'もデリミタとして利用可能です。 用法: /This is a pen/ #foo bar# +[A-Z]+
・メタ文字 パターン中にメタ文字を記述することができます。 ’\’ 一般的なエスケープ文字を表します。 ’^’ 検索対象の始まりを表します。 ’$’ 検索対象の終わりを表します。 ’.’ 改行を除くすべての文字が該当します。 ’[’ 文字クラス定義の開始を表します。 ’]’ 文字クラス定義の終了を表します。 ’|’ 選択枝の開始を表します。 ’(’ サブパターンの開始を表します。 ’)’ サブパターンの終了を表します。 ’?’ 繰り返し方法を指定します。 ’*’ 0 回以上の繰り返しを表します。 ’+’ 1 回以上の繰り返しを表します。 ’{’ 最小/最大の指定開始を表します。 ’}’ 最小/最大の指定終了を表します。
なお、角カッコを用いる文字クラスでは以下のメタ文字のみ利用可能です。 ’\’ 一般的なエスケープ文字を表します。 ’^’ クラスの否定を意味します。 ’-’ 文字の範囲を指定します。
・エスケープシーケンス エスケープ文字は'\'(バックスラッシュ)で始まる特殊文字です。 ’\a’ アラーム、ベル文字を表します。 ’\cx’ 'control-x', x は任意の文字を指定します。 ’\e’ エスケープ文字を表します。 ’\f’ 改ページ を表します。 ’\n’ 改行を表します。 ’\p{xx}’ xx プロパティを持つ文字を表します。 ’\P{xx}’ xx プロパティを持たない文字を表します。 ’\r’ キャリッジ・リターンを表します。 ’\R’ 改行の\n、\r、\r\n に該当します。 ’\t’ タブを表します。 ’\xhh’ 16 進コードで hh の文字を表します。 ’\ddd’ 8 進コードで ddd の文字を表します。
・Unicode文字 Unicodeで規定されているプロパティコードが指定可能です。 ・アンカー '^'(ハット)で対象文字列の先頭を表します。'$'(ドル)で対象文字列の最後を表します。 ・ドット '.'(ドット)で対象文字列の任意の1文字に該当します。 ・選択肢 '|'(パイプ)で文字列の選択肢を設定します。 ・サブパターン '()'(丸カッコ)で括られたパターンで、選択肢の範囲を指定します。
・繰り返し * 0回以上の繰り返しで、{0,} と同じ意味となります。 + 1回以上の繰り返しで、{1,} と同じ意味となります。 ? 直前の文字を0回または1回繰り返しで、{0,1} と同じ意味となります。
・後方参照 後方参照は文字クラス外で先にマッチしたパターンを使います。 ・言明 '?='は肯定の言明、'?!'は否定の言明です。 戻り読み言明の'?<='は肯定の言明、'?<!'は否定の言明を表します。 ・再試行なしサブパターン '(?>'で始まるカッコはパターンの一部がマッチしたら再評価されません。 ・条件付きサブパターン (?(条件)真パターン)と(?(条件)真パターン|偽パターン)があります。 ・コメント '(?#'ではじまり、')'で終わる文字列はコメント文字として処理から除外します。 参考:PHP マニュアル PCREのパターン構文
PHPの正規表現の関数は?
PHPでは正規表現を抽出・置換の関数で用います。正規表現対応の関数はPCRE関数で、PCRE関数の一覧は以下の通りです。
・preg_filter関数 正規表現による検索と置換を行う関数で、マッチした結果のみを返します。 ・preg_grep関数 パターンにマッチする配列の要素を返す関数です。 ・preg_last_error_msg関数 最後に実行した PCRE 正規表現に関するエラーメッセージを返す関数です。 ・preg_last_error関数 直近の PCRE 正規表現処理のエラーコードを返す関数です。 ・preg_match_all関数 繰り返し正規表現検索を行う関数です。 ・preg_match関数 pattern で指定した正規表現によるマッチングを行う関数です。 ・preg_quote関数 正規表現文字を特殊文字の前にバックスラッシュを挿入しクオートする関数です。 ・preg_replace_callback_array関数 正規表現検索を行い、コールバック関数を使用してターン単位で置換を行う関数です。 ・preg_replace_callback関数 正規表現検索を行い、コールバック関数を指定して置換を行う関数です。 ・preg_replace関数 正規表現検索および置換を行う関数です。 ・preg_split関数 正規表現で指定した文字列を分割する関数です。
PCRE関数の具体的な使い方は後ほど紹介します。 参考:PHP マニュアル PCRE 関数
PHPで正規表現の事例サンプル
正規表現の活用は主に抽出と置換です。この2つの分類を見てきましょう。
・正規表現の抽出 正規表現の抽出の代表的な関数はpreg_match()です。したがって、以降でpreg_match関数を用いて抽出の事例サンプルを紹介していきます。
・正規表現の置換 正規表現の置換の代表的な関数はpreg_replace()です。したがって、以降でpreg_replace関数を用いて置換の事例サンプルを紹介していきます。
正規表現の抽出事例サンプル
preg_match関数は正規表現によるマッチング抽出を行う関数です。抽出条件にマッチした全ての文字列を入手する場合はpreg_match関数の代わりにpreg_match_all関数を用います。 構文: preg_match( string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0 ): int|false 用法: if (preg_match($pattern, $subject)) 一致時の処理(1); else 不一致時の処理;(0) $pattern 正規表現パターンを入力します。 $subject 検索対象文字列を入力します。 $matches 省略可能、指定した場合は検索結果の文字列が入ります。
これから抽出サンプルを見てきます。preg_match関数に以下の変数をいれると抽出できます。 ・数字のみを検索する $subject マッチするのは任意の数字のみとします。 $pattern ‘/^[0-9]+$/’ ・郵便番号を検索する $subject マッチするのは'123'または'1234567'または'123-4567'の数字とします。 $pattern ‘/^\d{3}$|^\d{7}$|^\d{3}-\d{4}$/’ ・携帯電話番号を検索する $subject マッチするのは'123-4567-8910'または'12345678910'の数字とします。 $pattern ‘/^\d{3}-\d{4}-\d{4}$|^\d{11}$/’ ・全角文字があるか判断する $subject マッチするのは全角とします。 $pattern '/[^\x01-\x7E]+/'
正規表現の置換事例サンプル
preg_replace関数は正規表現検索および置換を行う関数です。 構文: preg_replace( string|array $pattern, string|array $replacement, string|array $subject, int $limit = -1, int &$count = null ): string|array|null subject に関して pattern を用いて検索を行い、 replacement に置換します。 用法: $ret_string=preg_replace($pattern, $replacement, $subject); $pattern 正規表現パターンを入力します。 $replacement 置換文字列を入力します。 $subject 検索対象文字列を入力します。 $ret_string パターンマッチした場合置換え後の$subject、マッチしなかった場合元の$subjectを返します。
多くの正規表現パターンはすでに抽出サンプルで説明しました。以下は代表的な置換サンプルです。preg_replace関数に以下の3つの変数をいれると置換できます。 ・平成31年を令和元年に変換する $subject 年号を含む文字列とします。平成と31年の間のスペースを取り除きます。 $pattern '/平成 *31年/' $replacement '令和元年'
正規表現の抽出・置換事例サンプル
preg_match関数とpreg_replace関数の組み合わせプログラムで抽出・置換が実現できます。実際に動作する抽出・置換のサンプルコードは以下の通りです。
・令和と平成の和暦を西暦に変換し、その他の文字列はそのまま返す サンプルコード: <?php // この下の行の文字列を変更すると、'令和 元年'や'令和 XX年'、平成でも処理できます。 $subject='これは平成31年の報告書です';
$subject=preg_replace('/(元年)/','1年',$subject); // 先に'元年'を'1年'に変換します。 $pattern='/(令和|平成) *([0-9]+)年/'; // 令和と平成の正規表現パターンです。
if (preg_match($pattern, $subject, $matches)) { // 正規表現のパターンマッチを行います。 // var_dump($matches); で$matchesの値が分かりますので変数チェックする際おすすめです。 if ($matches[1]=='令和') { // 和暦が令和の場合の処理です。 $year_base=intval($matches[2])+2018; // 令和の場合、数値に 2018を追加します。 } elseif ($matches[1]=='平成') { // 和暦が平成の場合の処理です。 $year_base=intval($matches[2])+1988; // 平成の場合、数値に 1988を追加します。 } $year='西暦'.$year_base.'年'; // 数値から文字列に変換します。 echo preg_replace($pattern,$year,$subject); // 和暦を西暦に変換します。 } else { echo $subject; // 令和と平成以外は、そのまま表示します。 } ?> 実行例: ・$subject='これは平成31年の報告書です'; の場合、平成が西暦に変換され、 ‘これは西暦2019年の報告書です’ が表示されます。
・$subject='これは平成 31年の報告書です'; の場合、数字の前のスペースが取り除かれ、 ‘これは西暦2019年の報告書です’ が表示されます。
・$subject='これは平成元年の報告書です'; の場合、元年が数値に変換処理され、 ‘これは西暦1989年の報告書です’ が表示されます。
・$subject='これは令和 元年の報告書です'; の場合、スペースと元年が変換処理され、 ‘これは西暦2019年の報告書です’ が表示されます。
・$subject='これは令和 2年の報告書です'; の場合、令和も平成同様に計算結果が表示され、 ‘これは西暦2020年の報告書です’ が表示されます。
・$subject='これは昭和 2年の報告書です'; の場合、変換表示せずに、 ‘これは昭和 2年の報告書です’ が表示されます。
PHPの正規表現を理解したら多岐のデータ置換を進めましょう
ウェブシステムやIoTの活用により取扱いデータが増加しています。PHPはサーバサイドで実行するため、ログ収集やログ分析に最適です。正規表現が理解できたらウェブのアクセス分析や顧客リストの整備等にも活用できます。ぜひ色々と試してみることをおすすめします。
編集部オススメコンテンツ
アンドエンジニアへの取材依頼、情報提供などはこちらから