
本文介绍使用 Array_uintersect() 配合 strcasecmp() 实现不区分大小写的多词匹配,精准提取并比对 api 返回的成分字符串与预设关键词数组,解决大小写敏感导致的匹配失败问题。
在实际开发中,我们常需从 API 返回的非结构化文本(如 “Ingredients: Whey, bEEf, EgG, NuTs”)中提取关键词,并判断其中是否有任意一项属于预定义的敏感/关注成分列表(如 [‘Beef’, ‘Nuts’])。此时,简单的 array_intersect() 会因大小写差异而失效;而逐个 strtolower() 转换再搜索又低效且难以扩展。
推荐方案是使用 php 内置的 array_uintersect() —— 它支持自定义比较函数,可天然实现不区分大小写的交集计算:
$response = 'Ingredients: Whey, bEEf, EgG, NuTs'; $array = ['Beef', 'Nuts']; // 步骤1:从响应中安全提取成分列表(去除前缀、分割、清理空格和标点) $ingredients = array_map('trim', array_slice( preg_split('/[:,s]+/', $response), 1 )); // 步骤2:使用 strcasecmp 进行不区分大小写的交集计算 $matches = array_uintersect($array, $ingredients, fn($a, $b) => strcasecmp($a, $b)); // 步骤3:判断是否存在至少一个匹配项 if (!empty($matches)) { echo "True"; // 至少有一个成分命中 } else { echo "False"; }
✅ 关键优势说明:
- array_uintersect() 对两个数组执行交集运算,且逐元素调用回调函数比较,无需预先统一大小写;
- strcasecmp() 是 PHP 原生的二进制安全、大小写不敏感字符串比较函数,性能优于 strtolower() + == 组合;
- 正则 ‘/[:,s]+/’ 同时处理冒号、逗号及连续空白符,比仅用空格 explode(” “, …) 更鲁棒;
- array_slice(…, 1) 跳过 “Ingredients” 前缀,避免误匹配。
⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
- 若原始字符串含嵌套括号、引号或特殊分隔符(如 “Whey (hydrolyzed)”, Nuts”),建议升级为 preg_match_all() 提取纯单词;
- array_uintersect() 返回的是第一个数组中存在、且在第二个数组中找到匹配的元素(保留原始大小写),如需标准化输出,可额外映射 array_map(‘strtolower’, $matches);
- 确保 $array 和 $ingredients 均为一维索引数组,否则可能引发意外行为。
综上,该方法兼顾准确性、可读性与性能,是处理此类“模糊成分匹配”场景的专业级实践方案。