タイトル: 文字列の置換(replace)
SEOタイトル: PHP 文字列置換 完全ガイド(str_replace / preg_replace / strtr / Laravel Str)
| この記事の要点 |
|
結論: 場面別の選び方
| 場面 | 関数 |
|---|---|
| 単純な文字列置換 | str_replace() |
| 大文字小文字を区別しない | str_ireplace() |
| 正規表現を使いたい | preg_replace() |
| マッチ部分を関数で加工 | preg_replace_callback() |
| 位置と長さで部分置換 | substr_replace() |
| 複数キーを一気に | strtr() |
| 1 回だけ置換 | preg_replace + limit / 自前 |
str_replace の基本
// 単純な置換
$result = str_replace('apple', 'orange', 'I like apple.');
// 'I like orange.'
// 配列で複数 search → 全部 replace に置換
$result = str_replace(['a', 'i'], 'X', 'apple pie');
// 'XpplX pXX'
// 配列で 1:1 対応
$result = str_replace(
['apple', 'pie'],
['orange', 'cake'],
'apple pie'
);
// 'orange cake'
// 第 4 引数で置換回数を取得
$count = 0;
$result = str_replace('a', 'A', 'banana', $count);
// $result='bAnAnA', $count=3
str_ireplace(大小文字無視)
$result = str_ireplace('apple', 'orange', 'I LIKE APPLE.');
// 'I LIKE orange.' ← 元の APPLE が orange に
$result = str_ireplace([''], '', '');
// 'alert(1)' ← 簡易 XSS 除去(実用ではより厳密に)
preg_replace: 正規表現置換
// 数字をすべて削除
$result = preg_replace('/[0-9]+/', '', 'abc123def456');
// 'abcdef'
// 後方参照($1, $2, $3...)
$result = preg_replace(
'/(\d{4})-(\d{2})-(\d{2})/',
'$3/$2/$1',
'2026-06-11'
);
// '11/06/2026'
// 名前付きグループ
$result = preg_replace(
'/(?\d{4})-(?\d{2})/',
'${month}/${year}',
'2026-06'
);
// '06/2026'
// 配列を一括処理
$result = preg_replace(
['/foo/', '/bar/'],
['FOO', 'BAR'],
'foo bar baz'
);
// 'FOO BAR baz'
// 第 4 引数 limit で置換回数を制限
$result = preg_replace('/a/', 'X', 'banana', 1);
// 'bXnana' ← 最初の 1 回だけ
preg_replace_callback(マッチを関数で加工)
// マッチした数字を 2 倍に
$result = preg_replace_callback(
'/\d+/',
fn($m) => $m[0] * 2,
'a1 b2 c3'
);
// 'a2 b4 c6'
// HTML エスケープしつつ でラップ
$result = preg_replace_callback(
'/\[\[([^\]]+)\]\]/',
fn($m) => '' . htmlspecialchars($m[1]) . '',
'商品名: [[Apple <3>]] が新発売'
);
// '商品名: Apple <3> が新発売'
// 連番を割り振る
$counter = 0;
$result = preg_replace_callback(
'/
'
);
substr_replace(位置で置換)
// 位置 7 から 5 文字を置換
$result = substr_replace('Hello, World!', 'PHP ', 7, 5);
// 'Hello, PHP !'
// 末尾に挿入(length=0)
$result = substr_replace('foo', 'bar', 3, 0);
// 'foobar'
// マイナス指定で末尾から
$result = substr_replace('20260611', '__', -4, 2);
// '2026__11'
// クレジットカード番号マスク
$card = '1234-5678-9012-3456';
$masked = substr_replace($card, str_repeat('*', 9), 5, 9);
// '1234-*********-3456'
strtr(複数キー一括変換)
strtr は連想配列で複数の置換ペアを一度に処理します。str_replace との重要な違い: マッチが重なる場合、最も長いキーを優先します。
// 連想配列で一括変換
$result = strtr('hello world', [
'hello' => 'こんにちは',
'world' => '世界',
]);
// 'こんにちは 世界'
// テンプレート置換
$tpl = 'Hello, {name}! Today is {date}.';
$result = strtr($tpl, [
'{name}' => '太郎',
'{date}' => '2026-06-11',
]);
// 'Hello, 太郎! Today is 2026-06-11.'
// str_replace との違い: 長いキー優先
$result = strtr('aab', ['a' => '1', 'aa' => '2']);
// '2b' ← 'aa' が優先される
$result = str_replace(['a', 'aa'], ['1', '2'], 'aab');
// '11b' ← 順番通り 'a' から処理されて 'aa' は届かない
str_replace の罠
// ❌ 配列の順序で意図しない結果
$result = str_replace(['a', 'b'], ['b', 'a'], 'ab');
// 期待: 'ba'
// 実際: 'aa' ← 'a'→'b' した後の文字列に対し 'b'→'a' が走る
// ✅ strtr なら期待通り
$result = strtr('ab', ['a' => 'b', 'b' => 'a']);
// 'ba'
// ❌ NULL を渡すと PHP 8.1+ で警告
str_replace('a', null, 'abc');
// Deprecated: passing null to parameter
// ✅ 空文字を明示
str_replace('a', '', 'abc');
Laravel での書き方
use Illuminate\Support\Str;
// 単純置換
Str::replace('apple', 'orange', 'apple pie');
// 'orange pie'
// 最初の 1 回だけ
Str::replaceFirst('a', 'A', 'banana');
// 'bAnana'
// 最後の 1 回だけ
Str::replaceLast('a', 'A', 'banana');
// 'banAnA'... ではなく 'banAna' wait 'banAna'(最後の a だけ)
// 'banAna' → 正確には末尾の a を置換 → 'banAna'... 最後の 'a' のみ → 'banAna'
// 配列で複数置換(順次)
Str::replaceArray('?', ['太郎', '東京'], 'こんにちは ? さん、お住まいは ? ですね');
// 'こんにちは 太郎 さん、お住まいは 東京 ですね'
// 流暢インターフェース
$result = Str::of('hello world')
->replace('world', 'PHP')
->upper()
->limit(20);
// 'HELLO PHP'
パフォーマンス比較
| 関数 | 速度 | 備考 |
|---|---|---|
str_replace | ★★★ 最速 | 単純文字列なら最強 |
strtr (配列) | ★★ 速い | 長いキー優先で安全 |
preg_replace | ★ 遅い | 正規表現コンパイル分 |
preg_replace_callback | 遅め | 関数呼び出しコスト |
単純な文字列置換に preg_replace を使うのは無駄。str_replace で済むなら使いましょう。
マルチバイト文字列の置換
UTF-8 等のマルチバイト文字列も基本は str_replace / preg_replace で扱えます。ただし substr_replace はバイト単位なので注意:
// ✅ str_replace は UTF-8 安全
str_replace('日本', 'Japan', '私は日本人です');
// '私はJapan人です'
// ✅ preg_replace は /u 修飾子で UTF-8 モード
preg_replace('/[ぁ-ん]+/u', 'X', 'これはテスト');
// 'XテスX'
// ❌ substr_replace はバイト単位 → 文字途中で切れる可能性
substr_replace('日本語', 'JP', 0, 3);
// マルチバイト用は mb_substr + 文字列連結で自前実装
FAQ
Q: 1 回だけ置換したい
A: preg_replace('/foo/', 'bar', $s, 1) の第 4 引数 limit。または Laravel の Str::replaceFirst。
Q: 改行を置換したい
A: str_replace(["\r\n", "\r", "\n"], '。OS 差異(CRLF / LF / CR)を全部カバー。
', $s)
Q: 何文字目から何文字目を置き換えたい
A: substr_replace($s, $new, $start, $length)。マルチバイトの場合は mb_substr で自前構築。