2

我正在使用 PHP 中的一些代码从搜索引擎中获取引荐来源数据,从而为我提供用户输入的查询。

然后,如果存在,我想从该字符串中删除某些停用词。但是,这个词的两端可能有也可能没有空格。

例如,我一直使用 str_replace 来删除一个单词,如下所示:

$keywords = str_replace("for", "", $keywords);
$keywords = str_replace("sale", "", $keywords);

但如果 $keywords 值是“婴儿公式”,它会将其更改为“婴儿 mula” - 删除“for”部分。

无需为“for”和“for”创建进一步的str_replace - 是否有一个preg_replace 类型命令我可以使用它来删除给定的单词,如果它在任何一端都有空格?

我的想法是将所有停用词放入一个数组中并以这种方式逐步遍历它们,我怀疑 preg_replace 会比遍历多个 str_replace 行更快。

更新: 感谢你们使用以下组合解决:

$keywords = "...";
$stopwords = array("for","each");
foreach($stopwords as $stopWord)
{
    $keywords = preg_replace("/(\b)$stopWord(\b)/", "", $keywords);   
}
4

4 回答 4

1
$keywords = "...";
$stopWords = array("for","sale");
foreach($stopWords as $stopWord){
    $keywords = preg_replace("/(\b)$stopWord(\b)/", "", $keywords);
}
于 2012-11-30T10:41:26.740 回答
0

试试这个方法

$keywords = preg_replace( '/(?!\w)(for|sale)(?>!\w)/', '', $keywords );
于 2012-11-30T10:40:17.477 回答
0

您可以为此使用单词边界

$keywords = preg_replace('/\bfor\b/', '', $keywords);

或多个词

$keywords = preg_replace('/\b(?:for|sale)\b/', '', $keywords);
于 2012-11-30T10:43:31.397 回答
0

虽然 Armel 的答案会起作用,但它的表现并不理想。是的,您想要的输出将需要 wordboundaries 和可能不区分大小写的匹配,但是:

  1. 用括号括起来的字边界没有任何好处。
  2. 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意思是“从这里重新开始全串匹配”;它有效地释放了先前匹配的空间。然后匹配一个或多个空格并替换为空字符串。

于 2018-09-12T01:42:49.407 回答