Open Source Web Development Tutorials - Dev Shed
preg_replace_callback()関数を使いこなす!
(2009/02/05公開)
forループのあるpreg_replace_callback()
では、次の例としてforループを含むpreg_replace_callback()に移りましょう。
以下のような数字リストがあるとします。
- 1
- sum(2, 3)
- sum(5, 6, 7)
- sum(11, 20, 37, 40)
- this is example6
sum()をキーワードとするこれらの行から、奇数だけを合計して以下の結果を生成します。
- 1
- 3
- 12
- 48
- this is example6
では、preg_replace_callback()を使って、挑戦してみましょう。
<?php
$str = '- 1
- sum(2, 3)
- sum(5, 6, 7)
- sum(11, 20, 37, 40)
- this is example6
';
echo preg_replace_callback('/sum((.*?))/', 'process_numbers', $str);
function process_numbers($matches) {
$sum = 0;
foreach(explode(',', $matches[1]) as $n) {
if ($n%2==1) $sum += $n;
}
return $sum;
}
?>
以下の行で、
echo preg_replace_callback('/sum((.*?))/', 'process_numbers', $str);
キーワードsum()を含むすべての行を捕捉します。
直接置換文字列の代わりに、コールバック関数process_numbers()を呼び出します。
process_numbers()関数で、
function process_numbers($matches) {
$sum = 0;
foreach(explode(',', $matches[1]) as $n) {
if ($n%2==1) $sum += $n;
}
return $sum;
}
?>
explode()を使い、個々の数字を入手します。そして、それぞれの数字が奇数か否かを検証します。奇数であれば、合計に加算します。ループの最後で合計を返します。この合計が、preg_replace_callback()関数の置換文字列となります。
出力は、以下のとおりです。
str_replace()関数と単純なforループで、同じことができると考えているのではありませんか?
では、文字列が以下のような自由形式のテキストになったらどうでしょう?
$str = '
- 1 sum(2, 3) sum(5, 6, 7)
- sum(11, 20, 37, 40) this is a test
';
この場合にも、1行も変更しないで、まったく同じコードが使えます。
echo preg_replace_callback('/sum((.*?))/', 'process_numbers', $str);
function process_numbers($matches) {
$sum = 0;
foreach(explode(',', $matches[1]) as $n) {
if ($n%2==1) $sum += $n;
}
return $sum;
}
?>
そして、以下の結果が生成されます!
- 1 3 12
- 48 this is a test
これこそ、正規表現を使って自由形式テキストを処理する方法の素晴らしいところです!preg_replace_callback()関数を使うからこそ、直接関数であるpreg_replace ()では不可能な複雑な演算を実行することができるのです。
Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.









