【PHP8.x】preg_replace_callback()関数の使い方
preg_replace_callback関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
preg_replace_callback関数は、正規表現パターンにマッチした文字列を、ユーザーが定義したコールバック関数の戻り値に置き換える処理を実行する関数です。この関数は、文字列内の特定の部分を検索し、それらを動的に生成される値に置き換えたい場合に非常に強力なツールとなります。
具体的には、対象の文字列内で正規表現パターンに合致する箇所が見つかるたびに、指定されたコールバック関数が呼び出されます。このコールバック関数には、マッチした部分文字列全体と、正規表現でキャプチャされたサブパターンが配列として引数に渡されます。コールバック関数は、これらの情報をもとに何らかの処理を行い、その結果として返された文字列が、元のマッチした部分文字列の代わりに挿入されます。
これにより、単純な固定値による置換では実現できない、複雑な条件に基づく文字列の変換や、マッチした内容に応じた柔軟な整形が可能になります。例えば、日付形式の変換、特定のHTMLタグの内容の加工、あるいはマッチした数値に対する計算結果の挿入など、多岐にわたる用途で利用できます。処理が成功すると置換後の文字列が返され、エラーが発生した場合はNULLが返されます。
構文(syntax)
1<?php 2$subject = 'The original string has numbers like 10 and 20.'; 3$pattern = '/\d+/'; 4$callback = function (array $matches): string { 5 return (string)((int)$matches[0] * 2); 6}; 7$replaced_string = preg_replace_callback($pattern, $callback, $subject); 8?>
引数(parameters)
array|string $pattern, callable $callback, array|string $subject, int $limit = -1, int &$count = null
PHP:
- array|string $pattern: 検索する正規表現パターン。配列で指定すると、複数のパターンを順番に適用します。
- callable $callback: パターンにマッチした部分を処理するコールバック関数。
- array|string $subject: 検索対象の文字列または文字列の配列。
- int $limit = -1: 置換回数の上限。-1を指定すると無制限になります。
- int &$count = null: 置換された回数が格納される変数。参照渡しで渡されます。
戻り値(return)
array|string|null
preg_replace_callback関数は、正規表現にマッチした部分をコールバック関数によって置換した結果を、配列または文字列として返します。置換対象がなかった場合はnullを返します。
サンプルコード
PHP preg_replace_callbackで全置換する
1<?php 2 3/** 4 * preg_replace_callback の使用例:すべてのマッチに対してコールバック関数を実行し、置換する。 5 * 6 * @param string $subject 対象の文字列 7 * @return string 置換後の文字列 8 */ 9function replaceAllWithCallback(string $subject): string 10{ 11 $pattern = '/[aeiou]/'; // 母音 (a, e, i, o, u) にマッチする正規表現パターン 12 $callback = function (array $matches) { 13 return strtoupper($matches[0]); // マッチした母音を大文字に変換 14 }; 15 16 // preg_replace_callback を使用して、すべてのマッチに対してコールバック関数を実行 17 $result = preg_replace_callback($pattern, $callback, $subject); 18 19 return $result; 20} 21 22// 使用例 23$originalString = "hello world"; 24$replacedString = replaceAllWithCallback($originalString); 25 26echo "元の文字列: " . $originalString . PHP_EOL; // 出力: 元の文字列: hello world 27echo "置換後の文字列: " . $replacedString . PHP_EOL; // 出力: 置換後の文字列: hEllO wOrld 28 29?>
preg_replace_callback関数は、文字列の中から正規表現パターンにマッチする部分を検索し、マッチした部分をコールバック関数の実行結果で置換するPHPの関数です。第一引数$patternには正規表現パターンを指定します。第二引数$callbackには、マッチした文字列を処理するためのコールバック関数(無名関数や通常の関数)を指定します。このコールバック関数は、マッチした文字列全体を含む配列を引数として受け取り、置換後の文字列を返します。第三引数$subjectには、検索対象となる文字列を指定します。第四引数$limitは置換を行う最大回数を指定します。デフォルト値は-1で、これは制限なしを意味します。第五引数$countには、置換された回数が格納されます(参照渡し)。
上記のサンプルコードでは、replaceAllWithCallback関数がpreg_replace_callbackを使用して、文字列内のすべての母音(a, e, i, o, u)を大文字に変換しています。正規表現パターン/[aeiou]/は、これらの母音にマッチします。コールバック関数は、マッチした母音を大文字に変換するstrtoupper関数を使用しています。preg_replace_callbackは、$subject文字列内のすべての母音を検索し、見つかった各母音に対してコールバック関数を実行し、その結果で元の母音を置換します。最終的に、置換後の文字列がreplaceAllWithCallback関数から返されます。preg_replace_callback関数は、置換後の文字列、またはエラーが発生した場合はnullを返します。
preg_replace_callback関数は、正規表現にマッチした部分をコールバック関数で処理し置換する関数です。初心者の方は、引数の順番や型を間違えやすいので注意が必要です。$patternには正規表現を文字列で指定し、$callbackには呼び出す関数を指定します。$subjectは置換対象の文字列です。
コールバック関数は、マッチした文字列を含む配列を受け取ります。配列の最初の要素 $matches[0] がマッチ全体を表します。正規表現にグループがある場合は、$matches[1]、$matches[2]...にそれぞれのグループが格納されます。
preg_replace_callbackは、置換後の文字列を返しますが、エラーが発生した場合はnullを返します。返り値がnullの場合に備え、エラーハンドリングを行うようにしましょう。また、正規表現のエスケープ処理が適切に行われているか確認してください。特に、ユーザーからの入力値を$patternに含める場合は、サニタイズを徹底してください。
preg_replace_callback_arrayで複数パターン置換する
1<?php 2 3/** 4 * preg_replace_callback_array の使用例を示します。 5 * 複数の正規表現パターンに対し、それぞれ異なるコールバック関数を適用して文字列を置換します。 6 * 7 * @param string $subject 置換処理の対象となる文字列。 8 * @return string 置換処理が適用された後の文字列。 9 */ 10function applyMultipleRegexReplacements(string $subject): string 11{ 12 // `preg_replace_callback_array` は、複数の正規表現パターンと 13 // それらに関連付けられたコールバック関数を一度に適用する際に便利です。 14 // PHP 7.0 以降で利用可能です。 15 $patternsAndCallbacks = [ 16 // パターン1: "php" または "html" を見つけたら大文字に変換する (大文字小文字を区別しない) 17 '/php|html/i' => function (array $matches): string { 18 return strtoupper($matches[0]); 19 }, 20 21 // パターン2: 数字を見つけたら2倍にする 22 '/\d+/' => function (array $matches): string { 23 return (string)((int)$matches[0] * 2); 24 }, 25 26 // パターン3: "example" という単語を見つけたら "SOLUTION" に置き換える 27 '/\bexample\b/i' => function (array $matches): string { 28 return 'SOLUTION'; 29 }, 30 ]; 31 32 // `preg_replace_callback_array` を呼び出し、定義されたパターンとコールバックを適用します。 33 // - `$patternsAndCallbacks`: キーが正規表現パターン、値がコールバック関数の連想配列。 34 // - `$subject`: 置換対象の文字列。 35 // - `$limit`: 置換を適用する回数の上限。-1 は無制限を意味します。 36 // - `&$count`: (オプション) 実際に置換が行われた回数が格納される変数。 37 $modifiedSubject = preg_replace_callback_array( 38 $patternsAndCallbacks, 39 $subject, 40 -1, // 全ての出現を置換 41 $count // 置換回数がこの変数に格納される (この例では使用しない) 42 ); 43 44 // エラーが発生した場合(例えば、正規表現が不正な場合)は null が返される可能性があります。 45 // このサンプルでは単純化のため、null チェックは行いません。 46 if (is_null($modifiedSubject)) { 47 // 実際にはエラーハンドリングをここに記述 48 return $subject; // 処理失敗時は元の文字列を返すなど 49 } 50 51 return $modifiedSubject; 52} 53 54// --- サンプルコードの実行例 --- 55$originalText = "PHP is a scripting language. HTML is its markup partner. I need 5 examples of PHP code and 3 examples of HTML."; 56echo "元の文字列: " . $originalText . PHP_EOL; 57 58$processedText = applyMultipleRegexReplacements($originalText); 59echo "処理後の文字列: " . $processedText . PHP_EOL; 60 61// 別の例 62$anotherText = "My version is 8.4.12 of PHP. This example shows an expert's skill."; 63echo "元の文字列: " . $anotherText . PHP_EOL; 64$processedAnotherText = applyMultipleRegexReplacements($anotherText); 65echo "処理後の文字列: " . $processedAnotherText . PHP_EOL; 66 67?>
preg_replace_callback_arrayは、PHPで複数の正規表現パターンを同時に使用し、それぞれ異なる処理(コールバック関数)を適用して文字列の置換を行うための関数です。
この関数は、主に四つの引数を取ります。最初の引数である$patternsAndCallbacksは、キーに正規表現パターン、値にそのパターンにマッチした際実行されるコールバック関数を指定する連想配列です。コールバック関数は、マッチした部分文字列の情報を配列として受け取り、置換後の文字列を返します。次に、$subject引数には置換処理の対象となる文字列を指定します。$limit引数は置換を行う回数の上限で、デフォルト値の-1は全てのマッチを置換することを意味します。最後の&$count引数には、参照渡しで実際に置換が行われた回数が整数で格納されます。
関数が成功した場合の戻り値は、置換処理が適用された後の文字列です。もし正規表現の記述に誤りがあるなど、処理中にエラーが発生した場合はnullが返されます。
サンプルコードでは、「php」や「html」というキーワードを大文字に変換する、数字を見つけたら2倍にする、「example」という単語を「SOLUTION」に置き換える、という複数の置換ルールを定義しています。これらのルールを$patternsAndCallbacks配列にまとめてpreg_replace_callback_array関数に渡すことで、一つの文字列に対して複数の異なる加工処理を一度に効率良く適用し、柔軟な文字列変換を実現しています。
preg_replace_callback_arrayは、複数の正規表現パターンとそれぞれに対応するコールバック関数を一度に適用できる便利な関数で、PHP 7.0以降で利用可能です。引数の$patternsAndCallbacksは、キーが正規表現、値がコールバック関数の連想配列として渡します。コールバック関数にはマッチした文字列が$matches配列で渡され、$matches[0]で全体を取得できます。正規表現の記述ミスなどにより処理が失敗した場合、戻り値はnullとなるため、必ずnullチェックを行い、エラーハンドリングを実装してください。$limitで置換回数の上限、&$countで実際の置換回数を取得できます。
PHP preg_replace_callbackで数字を2倍にする
1<?php 2 3/** 4 * preg_replace_callback の基本的な使い方を示すサンプルです。 5 * 文字列内の数字を検出して、それらの値を2倍に置換します。 6 * 7 * @param string $text 置換対象の元の文字列。 8 * @return string 置換後の文字列。エラーが発生した場合はエラーメッセージ。 9 */ 10function replaceNumbersWithDoubledValue(string $text): string 11{ 12 // 1つ以上の数字(\d+)にマッチする正規表現パターン。 13 // スラッシュはデリミタです。 14 $pattern = '/\d+/'; 15 16 /** 17 * 正規表現にマッチした部分文字列を処理するためのコールバック関数です。 18 * preg_replace_callback は、マッチが見つかるたびにこの関数を呼び出します。 19 * 20 * @param array $matches マッチ結果を含む配列。 21 * $matches[0] はパターン全体にマッチした文字列です。 22 * @return string 置換後の新しい文字列。 23 */ 24 $callback = function (array $matches): string { 25 // マッチした数字の文字列を整数に変換します。 26 $number = (int) $matches[0]; 27 // 2倍にして、再度文字列として返します。これが置換後の値となります。 28 return (string) ($number * 2); 29 }; 30 31 // preg_replace_callback を使用して、指定されたパターンにマッチした部分を 32 // コールバック関数の結果で置換します。 33 // 成功した場合は置換後の文字列、失敗した場合は null を返します。 34 $result = preg_replace_callback($pattern, $callback, $text); 35 36 // エラーが発生した場合(preg_replace_callback が null を返した場合)の処理。 37 if ($result === null) { 38 return "エラーが発生しました: preg_replace_callback の実行に失敗しました。"; 39 } 40 41 return $result; 42} 43 44// === サンプル使用例 === 45 46// 置換を適用する元のテキストを定義します。 47$originalText = "今日の最高気温は25度で、最低気温は18度でした。"; 48echo "元のテキスト: " . $originalText . PHP_EOL; 49 50// 関数を呼び出して、数字を2倍に置換したテキストを取得します。 51$modifiedText = replaceNumbersWithDoubledValue($originalText); 52echo "変更後のテキスト: " . $modifiedText . PHP_EOL; 53 54// 別の例 55$anotherText = "商品の価格は1200円、割引後は900円です。"; 56echo "別の元のテキスト: " . $anotherText . PHP_EOL; 57$anotherModifiedText = replaceNumbersWithDoubledValue($anotherText); 58echo "別の変更後のテキスト: " . $anotherModifiedText . PHP_EOL; 59 60?>
preg_replace_callback関数は、与えられた文字列の中から特定のパターン(正規表現)に一致する部分を見つけ、その一致した部分を独自の処理で生成した文字列に置き換えることができるPHPの関数です。通常の文字列置換では実現できない、複雑な条件に基づいた動的な置換を行う際に活用されます。
この関数は主に3つの重要な引数を取ります。1つ目は、検索したいパターンを定義する正規表現($pattern)です。2つ目は、パターンに一致する部分が見つかるたびに呼び出されるコールバック関数($callback)です。このコールバック関数には、マッチした結果が配列として渡され、その配列の$matches[0]にはパターン全体にマッチした文字列が含まれます。コールバック関数は、マッチした部分をどのように置換するかを計算し、新しい文字列として返します。3つ目は、置換処理を行う対象の元の文字列($subject)です。
サンプルコードでは、preg_replace_callback関数を使って、入力された文字列内のすべての数字を検出し、それらの数字を元の値の2倍に変換して置換しています。例えば、「今日の最高気温は25度」という文字列があれば、「今日の最高気温は50度」のように数字だけが変換されます。
この関数の戻り値は、置換処理が成功した場合には置換後の新しい文字列が返されます。しかし、正規表現の記述に誤りがあるなど、処理中にエラーが発生した場合はnullが返されるため、サンプルコードではnullチェックを行い、エラーが発生した際のメッセージを表示しています。
正規表現パターンは、スラッシュなどのデリミタで囲む必要があります。これを忘れるとエラーになりますので注意してください。コールバック関数には、正規表現にマッチした文字列が配列として渡され、$matches[0]で取得できます。この関数は、置換後の新しい文字列を必ず返す必要がありますので、戻り値の型に注意してください。preg_replace_callback関数は、処理に失敗した場合nullを返します。サンプルコードのように戻り値をチェックし、適切にエラーを処理することが重要です。また、$limit引数で置換回数を制限したり、$count引数で実際に置換された回数を取得したりすることも可能ですので、必要に応じて活用を検討してください。
preg_replace_callback でコールバック関数から外部変数を更新する
1<?php 2 3/** 4 * preg_replace_callback のコールバック関数内で外部変数を操作するサンプル 5 * 6 * 文字列内の数字を2倍に変換し、変換された数字の数を参照渡しでカウントします。 7 * システムエンジニアを目指す初心者の方にも、クロージャの `use` キーワードを 8 * 用いて外部変数をコールバック関数内で利用・更新する方法を理解してもらうことを目的とします。 9 * 10 * @param string $subject 置換対象の文字列 11 * @param int &$processedCount コールバック関数で処理された数字の数を格納する変数(参照渡し) 12 * @return string 置換後の文字列 13 */ 14function doubleNumbersAndCount(string $subject, int &$processedCount): string 15{ 16 // preg_replace_callback を使用して、指定されたパターンにマッチした部分を置換します。 17 // 第二引数のコールバック関数は、マッチするたびに実行されます。 18 $result = preg_replace_callback( 19 '/\d+/', // 正規表現パターン: 1つ以上の数字にマッチ 20 function (array $matches) use (&$processedCount): string { 21 // ここはコールバック関数です。 22 // $matches[0] には、パターンにマッチした文字列全体(例: "1200")が入っています。 23 $number = (int) $matches[0]; // マッチした文字列を整数に変換 24 25 $processedCount++; // 外部で定義された $processedCount 変数をインクリメント 26 // `use (&$processedCount)` により、このコールバック関数は 27 // 外部の $processedCount 変数への参照を持つため、直接更新できます。 28 29 return (string) ($number * 2); // 変換した数字を2倍にして文字列として返します 30 // この戻り値が元の文字列のマッチした部分と置き換わります。 31 }, 32 $subject, // 置換対象の文字列 33 -1, // $limit: 全てのパターンを置換 (-1は無制限) 34 $pregReplaceCount // $count: preg_replace_callback 自体が置換した回数(今回例では未使用) 35 ); 36 37 return $result; // 置換後の文字列を返します 38} 39 40// --- サンプル実行 --- 41 42$originalText1 = "商品Aの価格は1200円、商品Bは500円です。"; 43$count1 = 0; // 処理回数を格納する外部変数。必ず事前に初期化します。 44 45$modifiedText1 = doubleNumbersAndCount($originalText1, $count1); 46 47echo "元のテキスト1: " . $originalText1 . PHP_EOL; 48echo "変換後のテキスト1: " . $modifiedText1 . PHP_EOL; 49echo "処理された数字の数1: " . $count1 . PHP_EOL . PHP_EOL; 50 51 52$originalText2 = "バージョン3.0から4.5にアップデート。"; 53$count2 = 0; // 別の実行のための外部変数 54 55$modifiedText2 = doubleNumbersAndCount($originalText2, $count2); 56 57echo "元のテキスト2: " . $originalText2 . PHP_EOL; 58echo "変換後のテキスト2: " . $modifiedText2 . PHP_EOL; 59echo "処理された数字の数2: " . $count2 . PHP_EOL; 60
preg_replace_callback関数は、文字列内で正規表現にマッチした部分を、独自のコールバック関数で処理し、その結果で置き換える際に利用されます。
この関数は、第一引数に正規表現パターン、第三引数に置換対象の文字列を受け取ります。第二引数に指定するコールバック関数は、正規表現パターンに一致する部分が見つかるたびに実行され、マッチした文字列の情報が配列として渡されます。コールバック関数が返した値が、元の文字列のマッチ部分と置き換わります。
サンプルコードでは、doubleNumbersAndCount関数内でpreg_replace_callbackを用いて、文字列内の数字(/\d+/)を2倍に変換しています。特に重要なのは、コールバック関数内で外部の変数$processedCountを操作している点です。これは、クロージャのuse (&$processedCount)という構文により、外部変数を参照渡しでコールバック関数内に持ち込むことで実現しています。これにより、コールバック関数が実行されるたびに$processedCountがインクリメントされ、処理された数字の数を正確にカウントできます。
preg_replace_callbackの戻り値は、置換処理後の文字列です。また、第五引数には&$countとして、関数自身が置換を行った回数を格納するための変数を参照渡しで渡すことも可能です。このサンプルでは、コールバック関数内で特定の処理回数を独自にカウントしており、単なる置換だけでなく、条件に合致する要素の集計といった複合的な処理に応用できることを示しています。
preg_replace_callbackのコールバック関数内で外部変数を変更したい場合は、use (&$変数名)のように参照渡しで指定する必要があります。もしuse ($変数名)とすると値がコピーされるだけで、元の外部変数は変更されないため注意が必要です。参照渡しで利用する外部変数は、コールバック関数が実行される前に必ず初期化(例: $count = 0;)してください。これにより、コールバック関数が処理された回数などを安全に外部で集計できます。この方法は、マッチした文字列の数や、特定の条件を満たした回数などを外部で追跡する際に役立ちます。また、preg_replace_callbackの第5引数である&$countは、関数自体が何回置換を行ったかを格納する引数であり、コールバック関数内で操作する変数とは異なる役割を持つことを理解しておきましょう。