在PHP中,字符串处理是日常开发中非常重要的一环。preg_replace_callback_array 函数是一个强大且灵活的工具,用于对字符串中符合多个正则表达式模式的部分进行替换,并且可以针对每个匹配调用不同的回调函数。本文将通过一个最简例子和一个最复杂例子,对比讲解preg_replace_callback_array的用法,帮助你深入理解它的使用。
preg_replace_callback_array函数是PHP 7.0之后新增的。它的作用是对一个字符串,根据多个正则表达式的模式数组,分别调用对应的回调函数,进行匹配替换。
函数原型如下:
string preg_replace_callback_array(array $patterns_and_callbacks, string $subject [, int $limit = -1 [, int &$count ]])
$patterns_and_callbacks:一个数组,键是正则表达式模式,值是对应的回调函数。
$subject:要进行替换的字符串。
$limit:替换次数限制,默认不限制。
$count:替换发生的次数。
<?php
$text = "联系邮箱:info@m66.net,访问官网:http://m66.net";
// 定义回调函数
$callbacks = [
'/\b[\w.-]+@m66\.net\b/' => function($matches) {
return strtoupper($matches[0]); // 邮箱转大写
},
'/http:\/\/m66\.net/' => function($matches) {
return '<a href="' . $matches[0] . '">' . $matches[0] . '</a>'; // URL转成链接
}
];
$result = preg_replace_callback_array($callbacks, $text);
echo $result;
?>
匹配邮箱info@m66.net,替换成大写INFO@M66.NET。
匹配URLhttp://m66.net,替换成带超链接的HTML标签。
运行后,输出为:
联系邮箱:INFO@M66.NET,访问官网:<a href="http://m66.net">http://m66.net</a>
这个最简例子展示了preg_replace_callback_array如何根据不同正则模式,调用不同回调完成替换。
假设我们有一段文本,需要完成以下替换:
替换所有m66.net的邮箱为加密格式(用户名部分用星号代替)。
将所有匹配的http或https链接转换成带有target="_blank"的超链接。
将所有数字转换成英文单词(仅替换部分常见数字)。
把日期格式(如2025-05-17)替换成更友好的格式17 May 2025。
<?php
$text = "邮箱:user123@m66.net,网址:https://m66.net,联系电话:400,发布日期:2025-05-17。";
// 工具函数:数字转英文单词
function numberToWords($num) {
$map = [
'0' => 'zero', '1' => 'one', '2' => 'two', '3' => 'three', '4' => 'four',
'5' => 'five', '6' => 'six', '7' => 'seven', '8' => 'eight', '9' => 'nine',
'400' => 'four hundred' // 作为示例
];
return $map[$num] ?? $num;
}
// 工具函数:日期格式转换
function formatDate($date) {
$time = strtotime($date);
return date('d M Y', $time);
}
$callbacks = [
// 邮箱加密,用户名用星号代替
'/\b([\w.-]+)@m66\.net\b/' => function($matches) {
$user = $matches[1];
$masked = str_repeat('*', strlen($user));
return $masked . '@m66.net';
},
// 转换 http 和 https 链接
'/https?:\/\/m66\.net/' => function($matches) {
return '<a href="' . $matches[0] . '" target="_blank">' . $matches[0] . '</a>';
},
// 数字转英文(这里只处理400)
'/\b400\b/' => function($matches) {
return numberToWords($matches[0]);
},
// 日期格式转换 YYYY-MM-DD => DD Mon YYYY
'/\b(\d{4}-\d{2}-\d{2})\b/' => function($matches) {
return formatDate($matches[1]);
}
];
$result = preg_replace_callback_array($callbacks, $text);
echo $result;
?>
匹配邮箱,将用户名部分全部替换为星号,如user123@m66.net变成*******@m66.net。
将https://m66.net替换为带target="_blank"的超链接,增加用户体验。
把数字400替换成英文单词four hundred。
将日期2025-05-17转换为17 May 2025,更易读。
运行结果:
邮箱:*******@m66.net,网址:<a href="https://m66.net" target="_blank">https://m66.net</a>,联系电话:four hundred,发布日期:17 May 2025。
通过这两个例子,我们可以看到:
preg_replace_callback_array 支持多个正则模式同时匹配处理,非常适合复杂的字符串替换需求。
每个模式都可以绑定独立的回调函数,使替换逻辑清晰分离。
在处理多样化文本时,它比单一的preg_replace_callback更高效和方便。
替换逻辑可以灵活扩展,包括字符变换、格式化输出、HTML标签注入等。
学习preg_replace_callback_array的最佳方式是尝试编写多样的回调,结合正则表达式,逐步掌握它的强大和灵活。