如何基于参考字符串的数字映射替换目标字符串的数字为占位符?
解决方法
核心思路
先从参考字符串$a中提取去重且保留首次出现顺序的数字,构建「数字→占位符」的映射表,再通过闭包将映射表传入preg_replace_callback,对目标字符串$b进行精准替换。
完整代码实现
// 参考字符串 $a = 'abc123def456ghi123jkl789'; // 目标字符串 $b = 'xyz456mno123pqr000stu789'; // 1. 从$a中提取所有连续数字 preg_match_all('/\d+/', $a, $matches); // 2. 去重并保持首次出现的顺序 $uniqueNumbers = array_values(array_unique($matches[0])); // 3. 构建数字到占位符的映射关系 $numberMap = []; foreach ($uniqueNumbers as $index => $num) { $numberMap[$num] = "%d{$index}%"; } // 4. 替换$b中的目标数字 $result = preg_replace_callback('/\d+/', function($match) use ($numberMap) { $currentNum = $match[0]; // 存在映射则替换,否则返回原数字 return isset($numberMap[$currentNum]) ? $numberMap[$currentNum] : $currentNum; }, $b); // 输出结果:xyz%d1%mno%d0%pqr000stu%d2% echo $result;
关键细节说明
- 去重并保序:
array_unique会保留元素首次出现的位置,但会打乱索引,用array_values重新索引后得到顺序正确的数字数组。 - 闭包传参:通过闭包的
use ($numberMap)语法,将外部的映射表传入回调函数,这是解决「无法传递数组到回调」问题的核心。 - 精准匹配:正则
/\d+/匹配连续的数字串,确保只有和$a中完全一致的数字才会被替换(比如$a中的123不会替换$b中的12)。
示例验证
示例1
$a = '123abc456def123'→ 提取的唯一数字:['123', '456']$b = '456xyz123789'→ 替换结果:%d1%xyz%d0%789
示例2
$a = '98765test123test98765'→ 提取的唯一数字:['98765', '123']$b = '123abc98765def456'→ 替换结果:%d1%abc%d0%def456
内容的提问来源于stack exchange,提问作者Stefano Martini
相关产品推荐
相关产品推荐

