PHP Tips | 文字列処理:検索・置換 – 正規表現置換

PHP PHP
スポンサーリンク

正規表現置換って何をするもの?

まずイメージからいきます。

正規表現「マッチ」は、

「この文字列がパターンに当てはまるか?」
を調べるものでした。

正規表現「置換」は、

「パターンに当てはまる“部分”を、別の文字列に置き換える」
ためのものです。

普通の str_replace との違いはここです。

  • str_replace
    「完全に一致した文字列」を置き換えるだけ
  • 正規表現置換(preg_replace
    「パターンに当てはまる部分」を置き換えられる(“形”で指定できる)

例えば、

  • 数字だけを X に置き換える
  • 連続した空白を1つのスペースにまとめる
  • 郵便番号 1234567123-4567 の形に整形する

こういう「形ベースの置換」ができるのが、正規表現置換です。


PHP の基本:preg_replace の使い方

preg_replace のシグネチャ

基本形はこうです。

string|array|null preg_replace(
    string|array $pattern,
    string|array $replacement,
    string|array $subject,
    int $limit = -1,
    int &$count = null
)
PHP

初心者向けに、まずは一番シンプルな使い方だけ押さえればOKです。

  • $pattern:正規表現パターン(/.../ で囲む)
  • $replacement:置き換え後の文字列
  • $subject:対象の文字列
  • 戻り値:置き換え後の文字列

例1:数字を全部 X に置き換える

$text = "会員番号: 12345";

$result = preg_replace('/[0-9]/', 'X', $text);

echo $result;
// 会員番号: XXXXX
PHP

パターン /[0-9]/ は「0〜9 の数字1文字」。
それにマッチした部分を、すべて 'X' に置き換えています。


正規表現置換の「形」を意識する

例2:連続した空白を1つにまとめる

ユーザー入力などで、スペースが連続していることがあります。

$text = "PHP   ユーティリティ   解説";
PHP

これを「スペース1つ」にそろえたいとき、
preg_replace ならこう書けます。

$text = "PHP   ユーティリティ   解説";

$result = preg_replace('/\s+/', ' ', $text);

echo $result;
// PHP ユーティリティ 解説
PHP

パターン /\s+/ は、

  • \s:空白文字(スペース、タブ、改行など)
  • +:1回以上の繰り返し

つまり、「1文字以上連続した空白」を意味します。

それを ' '(スペース1つ)に置き換えることで、
「どれだけ連続していても、最終的にスペース1つ」にできます。

ここでの重要ポイントは、

「何文字あるか分からないもの」を、
「パターン(\s+)」で一気に扱える

というところです。


キャプチャと , を使った「形の変換」

正規表現置換の真骨頂は、
「マッチした一部を再利用しながら、形を変える」ことです。

例3:郵便番号 1234567 → 123-4567 に整形する

ユーザーがハイフンなしで入力してきた郵便番号を、
123-4567 の形に整えたいとします。

$text = "〒1234567 東京都...";

$result = preg_replace('/([0-9]{3})([0-9]{4})/', '$1-$2', $text);

echo $result;
// 〒123-4567 東京都...
PHP

ここでのパターン /([0-9]{3})([0-9]{4})/ を分解すると:

  • ([0-9]{3}):数字3桁 → キャプチャグループ1
  • ([0-9]{4}):数字4桁 → キャプチャグループ2

置換文字列 '$1-$2' は、

  • $1:1つ目のカッコにマッチした部分(3桁)
  • $2:2つ目のカッコにマッチした部分(4桁)

という意味です。

つまり、

「3桁」と「4桁」を見つけて、
「3桁-4桁」の形に並べ替える

という変換を1行でやっています。

ここが正規表現置換の一番おいしいところです。


実務ユーティリティとして関数にまとめる

連続空白を1つにするユーティリティ

よく使う「空白の正規化」を関数にしておきます。

/**
 * 連続した空白をスペース1つにまとめる
 */
function normalizeSpaces(string $text): string
{
    return preg_replace('/\s+/', ' ', $text);
}
PHP

使い方はシンプルです。

$input = "PHP   ユーティリティ   解説";

echo normalizeSpaces($input);
// PHP ユーティリティ 解説
PHP

郵便番号を 123-4567 形式に整えるユーティリティ

/**
 * 郵便番号(数字7桁 or 3桁-4桁)を 123-4567 形式に整形
 */
function formatZipCode(string $zip): string
{
    // 数字だけ7桁なら 123-4567 に変換
    $zip = preg_replace('/^([0-9]{3})([0-9]{4})$/', '$1-$2', $zip);

    return $zip;
}

echo formatZipCode("1234567");  // 123-4567
echo formatZipCode("123-4567"); // 123-4567(そのまま)
PHP

ここでは、^$ を付けて「全体が7桁の数字」のときだけ変換するようにしています。


置換のときにハマりやすいポイント

パターンが「広すぎる」と、思わぬところまで変わる

例えば、メールアドレスの @ より前だけマスクしたいとします。

$text = "contact: user@example.com";

$result = preg_replace('/.+@/', '***@', $text);

echo $result;
// contact: ***example.com  ← あれ? @ が消えた?
PHP

パターン /.+@/ は「できるだけ長くマッチ」するので、
contact: user@ の部分全体がマッチしてしまいます。

これを避けるには、「できるだけ短くマッチ」させる工夫が必要です。

$result = preg_replace('/[^@]+@/', '***@', $text);

echo $result;
// contact: ***@example.com
PHP

[^@]+ は「@ 以外の文字が1文字以上」。
これなら、「@ の直前まで」だけをマッチさせられます。

ここでの学びは、

「どこまでマッチさせたいか」を、
ちゃんとパターンでコントロールする

ということです。


まとめ:今日からの「正規表現置換」ユーティリティ

押さえておきたいポイントをコンパクトにまとめます。

  • preg_replace($pattern, $replacement, $text) で、「パターンにマッチした部分」を置き換えられる。
  • \s+ で「連続した空白」、[0-9]{3} で「数字3桁」など、「形」をパターンで表現する。
  • (...) で囲んだ部分は $1, $2 として置換側で再利用できる。
  • 実務では、「空白の正規化」「郵便番号の整形」「IDのマスク」などをユーティリティ関数にしておくと、コードがかなりスッキリする。

タイトルとURLをコピーしました