PHP函数开发:提取指定关键词后的目标子串(去重取最后)
解决方案
先修正原代码的核心问题,实现符合需求的功能:
function getKeyedSections($text, $keys) { // 转义关键词,避免正则特殊字符干扰匹配 $escapedKeys = array_map('preg_quote', $keys); // 构建正则模式:匹配完整关键词,捕获后续直到下一个关键词或文本结尾的内容 $pattern = '/\b(' . implode('|', $escapedKeys) . ')\b\s*(.*?)(?=\s*\b(' . implode('|', $escapedKeys) . ')\b|\z)/s'; preg_match_all($pattern, $text, $matches, PREG_SET_ORDER); $result = []; // 遍历匹配结果,重复关键词用最后一次出现的内容覆盖之前的 foreach ($matches as $match) { $key = $match[1]; $content = trim($match[2]); $result[$key] = $content; } // 只保留输入$keys中存在的关键词(未在文本中出现的关键词不纳入结果) return array_intersect_key($result, array_flip($keys)); }
关键说明
- 正则逻辑:
\b:使用单词边界确保匹配完整关键词,避免部分匹配(比如不会把"one"匹配进"someone")(.*?):非贪婪捕获关键词后的内容,直到遇到下一个关键词或文本结束(?=...):正向预查界定内容结束位置,不消耗匹配字符/s修饰符:让.匹配换行符,支持多行文本场景
- 保留最后一次出现:遍历匹配结果时,后续出现的同关键词会覆盖之前的记录,自然保留最后一次的内容
- 过滤无关内容:用
array_intersect_key确保结果仅包含输入的关键词列表中的项
测试验证
用示例输入测试:
$text = 'Lorem Ipsum is simply one dummy text of the printing and two typesetting industry. Lorem Ipsum has been the industry\'s one standard dummy text ever since the three 1500s.'; $keys = ['one', 'two', 'three']; print_r(getKeyedSections($text, $keys));
输出结果:
Array ( [one] => standard dummy text ever since the [two] => typesetting industry. Lorem Ipsum has been the industry's [three] => 1500s. )
完全符合期望要求。
内容的提问来源于stack exchange,提问作者WatcherD
相关产品推荐
相关产品推荐

