Menu

PHPのpreg_replace():正規表現で置換、後方参照の使い方

preg_replace($pattern, $replacement, $subject)は正規表現に一致するすべての部分を置換します:preg_replace('/\s+/', ' ', $text)は連続する空白を1つにまとめます。$1のような後方参照、preg_replace_callback、英数字以外の文字の削除、上限と回数を学びます。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

preg_replace($pattern, $replacement, $subject)は、文字列の中で正規表現に一致する部分をすべて見つけて置換します。preg_replace('/\s+/', ' ', $text)は、連続する空白、タブ、改行をすべて1つの空白にします。

元の文字列は変わらず、preg_replace()は新しい文字列を返します。\bは単語の境界を表すので、catsはそのまま残ります。

後方参照:1、1、{1}、\1

置換文字列の中では、$1が1つ目のキャプチャグループに一致したもの、$2が2つ目、$0が一致全体を表します。一致したテキストを並べ替えるのに使います。

置換文字列はシングルクォートで書きましょう。ダブルクォートの中では、"\1"は8進数のエスケープ(バイト0x01)になり、"${1}"は1という名前の変数として読まれます。この変数は未定義で、しかもPHP 8.2で非推奨になった文字列の構文です。シングルクォートの'\1'は'$1'と同じように動きますが、$1のほうが一般的な書き方です。

英数字以外の文字を取り除く

否定の文字クラス[^...]は、並べていないものすべてに一致します。それを''で置換すれば取り除けます。ほかの言語のテキストには、u修飾子とUnicodeのクラス\p{L}(任意の文字)と\p{N}(任意の数字)を使いましょう。そうしないとé、ü、すべての日本語の文字が消えてしまいます。

URLのスラッグを作る

いくつかのパターンを続けて使えば、タイトルをURLのスラッグにできます。先に小文字にし、英数字以外の連続をそれぞれ1つのハイフンに置換し、最後に両端のハイフンを取り除きます。

複数のパターン、上限、回数

$patternと$replacementには配列も使えます。各パターンは同じ位置の置換値に、順番に置き換えられます。4つ目の引数はパターンごとの置換の上限(-1は無制限)、5つ目には行われた置換の回数が入ります。

preg_replace_callbackで置換する値を計算する

置換する値が一致した内容によって変わるなら、preg_replace_callback()を使います。一致ごとに$matches配列を引数として関数を1回呼び、関数が返したものを挿入します。アロー関数を使えば、短いコールバックを1行に収められます。

複数のパターンにそれぞれ別の関数が必要なときは、preg_replace_callback_array()がpattern => callbackのペアの配列を受け取ります。

変数から来る置換テキスト

置換文字列の中の$やバックスラッシュには意味があるので、ユーザーやデータベースから来た置換文字列は崩れることがあります。$10という価格は存在しないグループ10への参照として読まれ、空になってしまいます。

検索するテキストも置換するテキストもパターンでないなら、str_replace()のほうが簡単で速い選択です。置換する前にパターンを試すには、preg_match()を参照してください。

よくある質問

preg_replaceで後方参照を使うには?

置換文字列の中でキャプチャグループを$1、$2(または\1)として参照します:preg_replace('/(\d{4})-(\d{2})-(\d{2})/', '$3/$2/$1', '2026-03-14')は"14/03/2026"を返します。置換文字列はシングルクォートで書き、参照の直後に数字が続くときは${1}を使います。

PHPで英数字以外の文字をすべて取り除くには?

preg_replace('/[^a-zA-Z0-9]/', '', $s)はASCIIの英字と数字だけを残します。あらゆる言語の文字(é、ü、日本語)を残すには、u修飾子とUnicodeのクラスを使います:preg_replace('/[^\p{L}\p{N}]/u', '', $s)。

preg_replaceとpreg_replace_callbackの違いは何ですか?

preg_replace()は$1のプレースホルダーを含む固定の置換文字列を受け取ります。preg_replace_callback()は一致ごとに関数を呼び、その戻り値を使うので、置換する値を計算できます。大文字にする、計算する、配列で引く、などです。

str_replaceとpreg_replaceのどちらを使うべきですか?

固定のテキストを置換するならstr_replace()を使います。速く、エスケープも不要です。連続する空白、任意の数字、単語の境界のように、置換するテキストがパターンに従うならpreg_replace()を使います。

preg_replaceで最初の一致だけを置換するには?

4つ目の引数に上限を渡します:preg_replace('/\d+/', '#', 'a1 b2 c3', 1)は"a# b2 c3"を返します。参照で渡す5つ目の引数には、行われた置換の回数が入ります。

Coddyのプログラミング言語のイラスト

Coddyでコードを学ぼう

始める