1. ホーム
  2. PHP

【PHP】preg_match の使い方|正規表現でパターンマッチ・抽出を行う方法

Share

「文字列が郵便番号の形式になっているか確認したい」「文章の中から日付の部分だけ取り出したい」——こうしたパターンに一致するかの判定や、一部の抜き出しに使えるのが正規表現と preg_match() 関数です。この記事では、正規表現の基本的な書き方と、preg_match() でマッチ判定・値の抽出を行う方法を、初心者の方にも分かるように解説します。

preg_match() とは

preg_match() は、文字列が指定したパターン(正規表現)に一致するかどうかを調べる関数です。正規表現とは「文字の並びのルール」を記号で表したもので、たとえば「数字が3つ並んでいる」「@ を含むメールアドレスの形」といった条件を1行で表現できます。

戻り値は、一致が見つかれば 1、見つからなければ 0、エラー時は false です。基本の書き方は次のとおりです。

sample.php
<?php
$text = "電話番号は 03-1234-5678 です";

// 「数字 - 数字 - 数字」のパターンに一致するか
if ( preg_match( '/\d+-\d+-\d+/', $text ) ) {
    echo "電話番号のような形式が含まれています";
} else {
    echo "見つかりませんでした";
}

第1引数がパターン、第2引数が調べたい文字列です。パターンは /(スラッシュ)で囲むのが基本で、この囲み文字をデリミタと呼びます。\d は「数字1文字」、+ は「直前の文字の1回以上の繰り返し」を表すので、\d+ で「1桁以上の数字」という意味になります。

よく使う正規表現の記号

正規表現は記号の意味さえ分かれば読み書きできます。まずは特に出番の多いものを押さえておきましょう。

記号意味
\d数字1文字(0〜9)
\w英数字またはアンダースコア1文字
.任意の1文字
+直前の文字の1回以上の繰り返し
*直前の文字の0回以上の繰り返し
{n}直前の文字をちょうど n 回
[abc]角かっこ内のいずれか1文字
^ / $文字列の先頭 / 末尾

たとえば「数字ちょうど7桁」は \d{7}、「先頭から末尾まで全部が数字」は ^\d+$ と書けます。^$ で挟むと「文字列全体がパターンに一致するか」を厳密にチェックできるため、入力値の検証でよく使います。

入力値が正しい形式か検証する

フォームの入力チェックは preg_match() の代表的な使い道です。郵便番号(3桁-4桁)の形式になっているかを確認する例を見てみましょう。

validate.php
<?php
$zip = "150-0001";

// ^ と $ で「全体が 3桁-4桁ちょうど」かを厳密に判定
if ( preg_match( '/^\d{3}-\d{4}$/', $zip ) ) {
    echo "正しい郵便番号の形式です";
} else {
    echo "形式が正しくありません";
}

^\d{3}-\d{4}$ は「先頭から、数字3つ・ハイフン・数字4つ、で末尾」という意味です。^$ がないと文字列の一部にこの並びが含まれていればマッチしてしまうため、厳密な検証では先頭・末尾の指定を忘れないようにします。

マッチした部分を取り出す

preg_match() の第3引数に変数を渡すと、マッチした文字列がその変数に配列として入ります。さらにパターンの一部を ( ) (丸かっこ)で囲んでおくと、その部分だけを個別に取り出せます。この丸かっこをキャプチャグループと呼びます。

extract.php
<?php
$text = "公開日: 2026-06-13 です";

// 年・月・日をそれぞれ ( ) で囲んで取り出す
if ( preg_match( '/(\d{4})-(\d{2})-(\d{2})/', $text, $matches ) ) {
    echo $matches[0]; // 2026-06-13(マッチ全体)
    echo $matches[1]; // 2026(1つ目のかっこ)
    echo $matches[2]; // 06  (2つ目のかっこ)
    echo $matches[3]; // 13  (3つ目のかっこ)
}

第3引数の配列には、次のルールで結果が入ります。インデックスの 0 番が特別な意味を持つ点を押さえておきましょう。

要素入る値
$matches[0]パターン全体に一致した文字列
$matches[1]1つ目の ( ) に一致した部分
$matches[2]2つ目の ( ) に一致した部分

このように、ログや文章から必要な部分だけを抜き出したいときに ( ) とキャプチャを組み合わせると便利です。

すべての一致をまとめて取得する

preg_match()最初に一致した1か所を見つけた時点で処理を止めます。文字列の中に複数ある一致をすべて取り出したいときは、preg_match_all() を使います。

all.php
<?php
$text = "在庫: りんご3個, みかん12個, ぶどう5個";

// 文字列中のすべての数字を取り出す
preg_match_all( '/\d+/', $text, $matches );

print_r( $matches[0] ); // ["3", "12", "5"]

「1つだけでいい」「形式チェックがしたい」なら preg_match()、「該当箇所を全部集めたい」なら preg_match_all()、と目的で使い分けます。

意図したようにマッチしないとき

パターンをデリミタで囲み忘れている

第1引数のパターンは '/\d+/' のように、必ず / などのデリミタで囲む必要があります。'\d+' のように囲み忘れると「No ending delimiter」という警告が出て、判定が false になります。文字列全体を囲っているか確認しましょう。

記号をそのままの文字として扱いたい

./ など、正規表現で特別な意味を持つ記号を「ただの文字」として一致させたいときは、直前に \(バックスラッシュ)を付けてエスケープします。たとえば URL のスラッシュを含めたい場合は \/ と書きます。パターン内にスラッシュが多いときは、デリミタを / 以外(例: #...#)にすると読みやすくなります。

大文字・小文字を区別したくない

初期状態では大文字と小文字は別の文字として扱われます。区別せずに一致させたいときは、終わりのデリミタの後ろに i を付けます。'/apple/i' とすれば “Apple” でも “APPLE” でもマッチします。この i のようにデリミタの後ろに付ける文字を修飾子と呼びます。

まとめ

preg_match() は、正規表現を使って文字列のパターン判定や抜き出しを行う関数です。要点を振り返っておきましょう。

  • パターンは / などのデリミタで囲み、戻り値は一致で 1・不一致で 0
  • ^$ で挟むと「文字列全体が一致するか」を厳密に検証できる
  • 第3引数を渡すとマッチ結果が配列で得られ、( ) で囲んだ部分を取り出せる
  • すべての一致を集めたいときは preg_match_all() を使う

正規表現は最初こそ記号が難しく見えますが、よく使うものは限られています。少しずつパターンを覚えていけば、入力チェックやテキスト処理が一気に楽になります。

参考ページ