「配列で一括置換」でやりたいことをイメージする
まず、やりたいことはこうです。
1回の処理で、「複数の文字列」をまとめて置き換えたい。
例えば、こんなケースです。
元の文字列: "PHP7 と PHP8 を比較する記事です。"
"PHP7" → "PHP 7.4"
"PHP8" → "PHP 8.3"
を一気に置き換えたい。
1個ずつ str_replace を呼ぶこともできますが、
PHP には「配列でまとめて置換する」仕組みが用意されています。
基本:str_replace に配列を渡す
str_replace の配列版の動き
str_replace は、第1引数・第2引数に配列を渡せます。
string|array str_replace(
string|array $search,
string|array $replace,
string|array $subject,
int &$count = null
)
PHPシンプルに言うと、
$searchが「探す文字列の配列」$replaceが「置き換え後の文字列の配列」$subjectが「対象の文字列」- 戻り値が「置き換え後の文字列」
です。
例1:複数の単語を一括置換する
$text = "PHP7 と PHP8 を比較する記事です。";
$search = ["PHP7", "PHP8"];
$replace = ["PHP 7.4", "PHP 8.3"];
$result = str_replace($search, $replace, $text);
echo $result;
// PHP 7.4 と PHP 8.3 を比較する記事です。
PHPここでのポイントは、
$search[0]→$replace[0]$search[1]→$replace[1]
という対応で置き換えが行われることです。
重要ポイント:配列の「順番」と「数」が対応していること
要素数が合っていないとどうなるか
$search と $replace の要素数が違うと、
余った方はそのまま使われます。
$text = "Apple and Google and Microsoft.";
$search = ["Apple", "Google", "Microsoft"];
$replace = ["A社", "G社"]; // 要素が2つしかない
$result = str_replace($search, $replace, $text);
echo $result;
// A社 and G社 and (Microsoft は空文字に置き換えられる)
PHP$replace に対応する要素がない場合は、
「空文字」として扱われてしまいます。
なので、
$searchと$replaceの要素数は必ずそろえる
というのが、とても重要です。
例題で感覚をつかむ
例2:顔文字や記号を絵文字風テキストに変換する
$text = "今日は :) だけど、昨日は :( だった。";
$search = [":)", ":("];
$replace = ["[ニコニコ]", "[しょんぼり]"];
$result = str_replace($search, $replace, $text);
echo $result;
// 今日は [ニコニコ] だけど、昨日は [しょんぼり] だった。
PHP1個ずつ str_replace を書くとこうなります。
$result = str_replace(":)", "[ニコニコ]", $text);
$result = str_replace(":(", "[しょんぼり]", $result);
PHP配列版を使うと、1行で意図が伝わるようになります。
例3:HTML の簡易サニタイズ(※あくまで簡易)
$text = '<b>太字</b>と<i>斜体</i>です。';
$search = ['<b>', '</b>', '<i>', '</i>'];
$replace = ['**', '**', '_', '_'];
$result = str_replace($search, $replace, $text);
echo $result;
// **太字**と_斜体_です。
PHPMarkdown 風に変換したい、などの軽い用途なら、
こういう「タグ → 記号」の一括置換もよくあります。
実務ユーティリティとして関数にまとめる
配列一括置換のラッパー
そのまま str_replace を使ってもいいのですが、
意味を分かりやすくするために、ラッパー関数にしてもよいです。
/**
* 配列で一括置換するユーティリティ
*
* @param array $search 探す文字列の配列
* @param array $replace 置き換え後文字列の配列
* @param string $text 対象文字列
* @return string
*/
function replaceMany(array $search, array $replace, string $text): string
{
return str_replace($search, $replace, $text);
}
PHP使い方はこうなります。
$text = "PHP7 と PHP8 を比較する記事です。";
echo replaceMany(
["PHP7", "PHP8"],
["PHP 7.4", "PHP 8.3"],
$text
);
// PHP 7.4 と PHP 8.3 を比較する記事です。
PHP「何をしているか」が関数名に出るので、
呼び出し側のコードが読みやすくなります。
大文字小文字を無視して一括置換したい場合
str_ireplace も配列を受け取れる
str_ireplace は、str_replace の「大文字小文字を無視する版」でしたが、
こちらも配列を受け取れます。
$text = "Apple and GOOGLE and MicroSoft.";
$search = ["apple", "google", "microsoft"];
$replace = ["Apple", "Google", "Microsoft"];
$result = str_ireplace($search, $replace, $text);
echo $result;
// Apple and Google and Microsoft.
PHP表記ゆれを一気に正規化したいときに、とても便利です。
置換の順番に注意が必要なケース
例4:入れ子になっているパターン
$text = "aaa";
$search = ["a", "aa"];
$replace = ["X", "Y"];
$result = str_replace($search, $replace, $text);
echo $result;
PHPこの結果は、少し直感とズレるかもしれません。
str_replace は、
$search[0]→$replace[0]を全部置換- 次に
$search[1]→$replace[1]を全部置換
という順番で処理します。
つまり、
"a"→"X"に置換 →"XXX""aa"→"Y"に置換 →"XXX"の中に"aa"はないので変化なし
結果は "XXX" になります。
「aa を先に置き換えたい」なら、順番を変える必要があります。
$search = ["aa", "a"];
$replace = ["Y", "X"];
$result = str_replace($search, $replace, $text);
// "YX"
PHPこのように、
「短い文字列」と「それを含む長い文字列」を同時に置換するときは、
順番に気をつける
というのが大事なポイントです。
まとめ:今日からの「配列で一括置換」ユーティリティ
押さえておきたいポイントをコンパクトにまとめます。
str_replaceは、第1・第2引数に配列を渡すと「複数の文字列」を一括置換できる。$searchと$replaceの要素数・順番が対応していることがとても重要。- 表記ゆれの統一や、簡単なマークアップ変換などでよく使える。
- 大文字小文字を無視して一括置換したいときは、
str_ireplaceを使う。 - 「短い文字列」と「それを含む長い文字列」を同時に置換するときは、順番に注意する。
