【PHP入門】正規表現で検索・抽出・置換する5つの関数を使い倒せ!

こんにちは!ライターのmuramatsuです。PHPでは正規表現を使用して、文字列の列処理が可能なのをご存知ですか?

この記事では、

  • 正規表現とは
  • 文字列をチェックする方法
  • 正規表現での抽出方法
  • 正規表現で置換する方法
  • 正規表現チェッカーの使い方

というように、基本的な内容から応用的な正規表現の使い方に関しても解説していきます。今回はそんなPHPの正規表現の使い方について、わかりやすく解説します!

目次

正規表現とは

正規表現は、文字列の集合を1つの形式で表すために使用します。1つの形式とは、分かりやすい例を挙げると、

  • 郵便番号
  • 住所
  • 電話番号
  • メールアドレス
  • 日付

など決められたルールに沿った形式「パターン」になっている文字列のことです。特定の文字列から、パターンを指定した文字列を検索・抽出・置換することが可能になります。

パターンは自分で設定することができるため、上記で挙げた例以外でも文字列であれば何でもパターンにすることができます。

例えば「Hello World!」をパターンと指定し、「Hello Words!」や「Hello Panda!」などの色々な文字列から「Hello World!」のパターンを検索したり、抽出したりができるのです。そのためPHPでは、正規表現が使用できる主に5つの関数が用意されています。

パターンにマッチした文字列を検索する

正規表現を使ってパターンを検索した際に、文字列がパターンに合っていることをマッチするといいます。ではどのようにして、パターンにマッチした文字列を検索するのか見ていきましょう。

preg_matchで検索する

新規登録などでユーザ情報を登録してもらう際に、連絡先やメールアドレスなどを入力することが出てきます。そこで、フォームに入力してもらった住所やメールアドレスなどが正しく登録されているか、検索(チェック)することができます。

正規表現を用いて特定の文字列を検索するには、preg_match関数を使用します。

基本構文

preg_match(‘/パターン/’,’検索対象文字列’);

第一引数は、パターン(正規表現)を指定ます。通常パターンを指定するときは、スラッシュ(/)でパターンを囲みます。第二引数に検索対象の文字列、または検索対象の文字列が代入された$変数や$配列を指定します。

preg_match関数は、戻り値にbool(真偽値)型の値を返しますので、指定したパターン(正規表現)に一致した文字列が存在した場合は、TRUEを返します。

以下にpreg_match関数を使用した、簡単な文字列チェックのサンプルを記述します。

<?php

$num_text = 'A1B2C3';

if (preg_match('/1/', $num_text)){
  echo '数値1が含まれています';
}else{
  echo '数値1は含まれていません';
}

?>

実行結果

数値1が含まれています

preg_match関数の第一引数のパターンには1を指定しています。第二引数には、検索対象の文字列が代入された変数$num_textを指定し、文字列「A1B2C3」の中に数値「1」が含まれているかチェックしています。

このサンプルではパターンを「1」としましたが、複数の数字を指定したい場合は「’/[123]/’」のように四角カッコ([ ])で数字を囲みます。四角カッコ([ ])は文字クラスを意味しています。

またPHPでは文字クラスの簡易表現が用意されています。先ほどのパターンを「’/[123]/’」と表現しなくても、数字を意味する「」または「¥d」を使って数値が含まれているかを判断することができます。

<?php

$num_text = 'A1B2C3';

//dを使って対象の文字列に数値がマッチしているか検索
if (preg_match('/d+/', $num_text)){
  echo '数値が含まれています';
}else{
  echo '数値は含まれていません';
}

?>

実行結果

数値が含まれています

ここでは「d」にプラス(+)をつけて1回以上数字が含まれているかを検索しています。

preg_match_allで文字列の全てを検索する

マッチするテキストを検索した後も、さらにマッチングを行うpreg_match_all関数があります。preg_match_all関数はパターン(正規表現)にマッチした全てのテキストを取得してくれます。

preg_match関数は基本的に最初にマッチしたテキストを返すため、第三引数を指定した場合、配列には最初にマッチしたテキストしか格納されません。検索対象文字列から全てのマッチした結果を配列に格納したい場合はpreg_match_all関数を使用します。

基本構文

preg_match_all(‘/パターン/’,’検索対象文字列’ [, &$配列]);

基本的にはpreg_matchと同じ書き方になります。第三引数を指定した場合、検索結果が代入されますが、マッチしたテキストが配列に格納されます。

サンプルコード
文字列にかかれているいくつかの電話番号を$tell_numに代入し、その中から携帯電話番号を取得します。

<?php

$tell_num = '03-1234-5678;
             090-1234-5678;
             050-1234-5678;
             0120-000-000;
             090-9876-5432;
             03-9876-5432;
             06-9876-5432;
             080-0987-6543;
             070-0123-4567';
            
//携帯電話番号の形式に一致するようにパターンを指定
preg_match_all('/(050|070|080|090)-d{4}-d{4}/', $tell_num, $cell_num);
 
 print_r($cell_num);

?>

実行結果

Array ( [0] => Array ( 
                         [0] => 090-1234-5678 
                         [1] => 050-1234-5678 
                         [2] => 090-9876-5432 
                         [3] => 080-0987-6543 
                         [4] => 070-0123-4567 
                        ) 
        [1] => Array ( 
                         [0] => 090 
                         [1] => 050 
                         [2] => 090 
                         [3] => 080
                         [4] => 070 
                        ) 
)

preg_match_all関数の第一引数のパターン「(050|070|080|090)」のカッコ「( )」はまとまりを意味し、棒線「 | 」はいずれかを意味しています。カッコ内では「050「070」「080」「090」のいずれか、という意味になります。

「-d{4}」のハイフン「-」は市外局番の後に含まれているハイフンを指定しています。dは数字を意味し、{4}は4回繰り返すことを意味しているので、数字を4回繰り返している文字列を指定しています。

$tell_numに代入されている文字列から指定した上記のパターンを検索し、マッチした結果を$cell_numの配列に格納し、print_rで配列の情報を出力しました。

正規表現を用いてさまざまな形式の文字列をチェックする方法については、以下の記事で詳しく解説しています。

正規表現で抽出する方法

対象の文字列を正規表現を使用して、指定したパターンに一致した文字列のみを抽出する場合はpreg_match関数やpreg_grep関数を使用します。

preg_matchでパターンを検索し抽出する

preg_match関数は、第三引数を指定することにより、指定したパターンにマッチした文字列を検索し、その結果を抽出することができます。

基本構文

preg_match(‘/パターン/’,’検索対象文字列’ [, &$配列]);

preg_match_all関数と同じように、第三引数を指定した場合はマッチした文字列が配列に格納されます。

以下にpreg_match関数を使用して、日付を抽出する簡単なサンプルを紹介します。

<?php

$date_text = '本日は2018/06/01です。';

//YYYY/MM/DDの日付形式を抽出する
preg_match('/d{4}/d{1,2}/d{1,2}/', $date_text, $date_match);

var_dump($date_match);

?>

実行結果

array(1) { [0]=> string(10) "2018/06/01" }

「YYYY/MM/DD」のパターンをまずは検索します。はじめに「YYYY」の部分にあたるパターンをpreg_match関数内d{4}で数字(d)4つ分({4})を指定します。次の年と月の間にあるスラッシュ(/) はバックスラッシュ()の後に書き、/と指定します。

スラッシュは正規表現のエスケープ文字(特殊文字)となるので、スラッシュの前にバックスラッシュ「」または円マーク「¥」をつける必要があります。

次に「MM」にあたる部分をd{1,2}で数字(d)1~2つ分({1,2})と指定します。「/DD」の部分も同じ要領で指定し、上記のパターンを検索します。検索した結果を抽出させ第三引数の$date_matchに代入し、var_dumpで日付と文字列の詳細を出力しました。

preg_grepで配列の要素から抽出する

preg_match関数では、指定した文字列の中からパターンを抽出しましたが、配列の要素からパターンを抽出するにはpreg_grep関数を使用します。

基本構文

preg_grep(‘/パターン/’,’検索対象の配列’ [, $フラッグ = 0]);

第三引数の$フラッグにPREG_GREP_INVERTを設定すると、パターンにマッチしない要素を返します。

サンプルコードで配列$infoに格納されている情報の中の郵便番号だけを抽出してみましょう。

<?php

$info = [
         '03-1234-5678',
         '〒162-0825',
         '東京都新宿区神楽坂',
         '090-1234-5678',
         '〒151-0073',
         '東京都渋谷区笹塚',
         '080-0987-6543',
         '〒171-0043',
         '東京都豊島区要町',
         '06-9876-5432',
         '〒151-0073',
         '東京都渋谷区笹塚',
         '080-0987-6543',
         '〒616-0024',
         '京都府京都市西京区嵐山宮町',
         '03-9876-5432',
         '〒153-0042',
         '東京都目黒区青葉台',
        ];

//郵便番号のみ抽出し$zipに代入する
$zip = preg_grep('/〒d{3}-d{4}/', $info);
 
print_r($zip);

?>
Array ( 
       [1] => 〒162-0825 
       [4] => 〒151-0073 
       [7] => 〒171-0043 
       [10] => 〒151-0073 
       [13] => 〒616-0024 
       [16] => 〒153-0042 
)

郵便番号の形式「〒〇〇〇-〇〇〇〇」を指定するため、preg_grep関数内でまずは郵便のマーク「〒」を指定します。次に3桁の数字とハイフン(-)を指定するのでd{3}-と指定します。最後に4桁の数字を指定するのでd{4}を指定します。

上記の検索したパターン結果を抽出し$zipに代入して、print_rで出力しました。それぞれの郵便番号が、配列$infoの1,4,7,10,13,16番目にあることが分かりますね。

正規表現を使用して特定の文字列を抽出する方法は、以下の記事でも詳しく解説しています!

正規表現で置換する方法

文字列を正規表現で指定した文字列に置換するためには、preg_replace関数を使用します。また、マルチバイト文字を置換する場合はmb_ereg_replace関数を使用します。

preg_replaceでマッチした文字列を置換する

preg_replace関数はマッチした文字列を指定した文字列に置換することができます。

基本構文

preg_replace(‘/パターン/’,’置換する文字列’, ‘置換対象の文字列’[, $リミット[, $カウント]]);

第一引数にはパターンを指定します。第二引数には置換する文字列、または置換する文字列が代入された変数、配列を指定します。第三引数には検索・置換対象となる文字列、または置換対象となる文字列が代入された変数、配列を指定します。

第四引数の$リミットは、置換対象となる文字列において、各パターンを行う最大回数を指定することができます。指定は必須ではありません。デフォルトは制限なしの設定になっています。第五引数の$カウントを指定すると、置換回数が渡されます。

返り値は、第三引数が配列の場合は配列を、 その他の場合は文字列を返します。以下にpreg_replace関数を使用した簡単なサンプルを紹介します。

<?php

$str = '2017年に開催された学際のスペシャルゲスト';

$str_grep = preg_replace('/2017/', '2018', $str);

echo $str_grep;

?>

実行結果

2018年に開催された学際のスペシャルゲスト

第一引数に検索対象文字列”2017”を指定し、第二引数に置換後の文字列”2018”を指定しています。

実行結果を見ると、2017年が2018年に置換されているのが分かりますね。

mb_ereg_replaceでマルチバイト文字を置換する

preg_replace関数では、文字列が半角英数字の場合に置換することができました。日本語のような全角のマルチバイトを置換する場合にはmb_ereg_replace関数を使用します。

基本構文

mb_ereg_replace(‘パターン’,’置換する文字列’, ‘置換対象の文字列’);

基本的にはpreg_replaceと同じ書き方になりますが、パターンを指定するときスラッシュ「/」で囲む必要はありません。

返り値は成功した場合に結果の文字列、エラー時に FALSE を返します。

<?php

$str = '雪のち晴れ';

$rep = mb_ereg_replace('雪', '雨', $str);

echo '変更前:'. $str. '<br>';
echo '変更後:'. $rep

?>

実行結果

変更前:雪のち晴れ
変更後:雨のち晴れ

文字列「雪のち晴れ」の「雪」を「雨」に変更するため、mb_ereg_replace関数内の第一引数に’雪’を、第二引数に’雨’を指定して、第三引数に置換したい文字列($str)を指定しました。実行結果を見ると、変更前と変更後で置換されていることが分かりますね。

正規表現を使用して文字列を置換する方法は、以下の記事でも詳しく解説しています!

正規表現チェッカーの使い方

正規表現は特定の文字列を操作するときに便利ですが、指定した文字列のみを置換・抽出などをしたい場合は、パターンを組み合わせて指定する必要があります。

正規表現にはさまざまなパターンがあり、全て覚えるのは面倒ですし、慣れないうちは特定の文字列を取得するために、試行錯誤を繰り返す羽目になると思います。

そこでPHPには正規表現を用いて、パターンにマッチした文字列操作の結果を簡単に確認できる正規表現チェッカーが用意されています。

PHPの正規表現チェッカーの使い方については、以下の記事で詳しく解説しています!

まとめ

ここでは、PHPで正規表現を使用するにあたり、正規表現の文字列を検索・抽出・置換する方法について解説しました。正規表現を使用して文字列を扱う処理はよく使用しますので、この機会にぜひ覚えておきましょう。

この記事を書いた人

世界中の人たちと友達になって、その友達の家を巡る旅をしたいと密かに思っている。

複雑な内容を誰にでもわかりやすく、そして納得のいくような解説をする、をモットーにしています!

目次