はじめに
preg_filter() は preg_replace() にそっくりですが、マッチした要素だけを返すという重要な違いがあります。
PHP8上級試験では、この挙動の違いがよく問われます。この記事では、実際のコードを例に動作の違いを確認しながら、試験対策として押さえておきたいポイントを整理します。
目次
🔹 preg_filter() の基本構文
preg_filter(
string|array $pattern,
string|array $replacement,
string|array $subject,
int $limit = -1,
int &$count = null
): string|array|nullこの関数は、正規表現による検索と置換を行い、マッチした要素だけを返す点が特徴です。
似た関数 preg_replace() はマッチしなかった要素もそのまま返すため、戻り値の配列の要素数が変わります。
🔹 サンプルコードで比較
<?php
declare(strict_types=1);
error_reporting(-1);
$pattern = '/\A([0-9]{3})([ -]?)([0-9]{4})\z/';
$replacement = '$1$3';
$subject = [
'123-4567',
'123 4567',
'1234-567',
'abcdef',
];
$r = preg_filter($pattern, $replacement, $subject);
var_dump($r);🔹 実行結果
array(2) {
[0]=>
string(7) "1234567"
[1]=>
string(7) "1234567"
}この結果からわかるように、マッチした「123-4567」と「123 4567」だけが置換されて返されていることが確認できます。一方、1234-567 と abcdef は正規表現にマッチしなかったため、結果に含まれません。
🔹 preg_replace() の場合
同じコードを preg_replace() に変更すると次のようになります。
$r = preg_replace($pattern, $replacement, $subject);
var_dump($r);結果はこうなります👇
array(4) {
[0]=>
string(7) "1234567"
[1]=>
string(7) "1234567"
[2]=>
string(8) "1234-567"
[3]=>
string(6) "abcdef"
}このように、マッチしなかった要素もそのまま返すのが preg_replace() の挙動です。
🧩 図解:preg_filter と preg_replace の違い
+----------------------------+
| $subject 配列 |
|----------------------------|
| '123-4567' → ✅マッチ |
| '123 4567' → ✅マッチ |
| '1234-567' → ❌非マッチ |
| 'abcdef' → ❌非マッチ |
+----------------------------+
preg_filter() → ['1234567', '1234567']
preg_replace() → ['1234567', '1234567', '1234-567', 'abcdef']🧭 まとめ
| 関数名 | マッチしなかった要素 | 戻り値の配列数 |
|---|---|---|
preg_filter() | 除外する | 減る |
preg_replace() | そのまま返す | 変わらない |
ポイント:
- 試験では「preg_filter() は preg_replace() の結果をフィルタしたもの」と覚えると整理しやすい。
preg_filter()はマッチしたデータだけ欲しいときに使う。
