虽然 Armel 的答案会起作用,但它的表现并不理想。是的,您想要的输出将需要 wordboundaries 和可能不区分大小写的匹配,但是:
- 用括号括起来的字边界没有任何好处。
preg_match()
对黑名单数组中的每个元素执行迭代调用效率不高。这样做将要求正则表达式引擎对整个字符串执行一波又一波的单个关键字检查。
我建议构建一个单一的正则表达式模式,该模式将在遍历字符串的每个步骤中检查所有关键字——一次。要动态生成单个模式,您只需要使用(管道)来内爆您的黑名单元素数组,这些|
(管道)表示正则表达式中的“OR”命令。通过将所有以竖线分隔的关键字包装在一个非捕获组 ( (?:...)
) 中,单词边界 ( \b
) 为黑名单数组中的所有关键字服务。
代码:(演示)
$string = "Each person wants peaches for themselves forever";
$blacklist = array("for", "each");
// if you might have non-letter characters that have special meaning to the regex engine
//$blacklist = array_map(function($v){return preg_quote($v, '/');}, $blacklist);
//print_r($blacklist);
echo "Without wordboundaries:\n";
var_export(preg_replace('/' . implode('|', $blacklist) . '/i', '', $string));
echo "\n\n---\n";
echo "With wordboundaries:\n";
var_export(preg_replace('/\b(?:' . implode('|', $blacklist) . ')\b/i', '', $string));
echo "\n\n---\n";
echo "With wordboundaries and consecutive space mop up:\n";
var_export(trim(preg_replace(array('/\b(?:' . implode('|', $blacklist) . ')\b/i', '/ \K +/'), '', $string)));
输出:
Without wordboundaries:
' person wants pes themselves ever'
---
With wordboundaries:
' person wants peaches themselves forever'
---
With wordboundaries and consecutive space mop up:
'person wants peaches themselves forever'
ps/ \K +/
是输入的第二个模式,preg_replace()
这意味着将第二次读取输入字符串以搜索 2 个或更多连续空格。 \K
意思是“从这里重新开始全串匹配”;它有效地释放了先前匹配的空间。然后匹配一个或多个空格并替换为空字符串。