【问题标题】:Strpos with exact matches具有完全匹配的 Strpos
【发布时间】:2011-12-05 17:16:46
【问题描述】:

我在 php 中有一个函数,我想对字符串执行简单的搜索,使用 kw 作为搜索短语,如果找到则返回 true。

这就是我现在拥有的:

for($i=0; $i<count($search_strings); $i++){
   $pos = strpos($search_strings[$i], $kw_to_search_for);
}

这很好用,并且确实在搜索的字符串中找到了关键字,但问题是 strpos 不匹配确切的短语或单词。

例如,如果字符串中包含单词 'PHP',则搜索 'HP' 将返回 true。

我知道 preg_split 和可用于进行完全匹配的正则表达式,但就我而言,我不知道每次搜索的 keyword 是什么,因为关键字是用户输入的

所以关键字可以是“hot-rods”、“AC/DC”、“Title:Subject”等... 这意味着我不能拆分单词并单独检查它们,因为我必须为正则表达式使用某种动态模式。

如果有人知道一个好的解决方案,我将不胜感激。

我的意思是,基本上我只想要完全匹配,所以如果 KW 是“Prof”,那么如果搜索字符串中的匹配是“Prof”并且周围没有任何其他字符,这将返回 true。
例如,“Professional”必须为 FALSE。

【问题讨论】:

  • 我有点困惑,您是否要求进行 str 比较?你不是在问:$search_strings[$i] === $kw_to_search_for是吗?
  • 我想我上当了,...doesn't have any other characters surrounding it。不过,如果要搜索一个词,@webbiedave 的解决方案是有意义的。

标签: php html regex


【解决方案1】:

您可以使用单词边界\b

if (preg_match("/\b".preg_quote($kw_to_search_for)."\b/i", $search_strings[$i])) {
    // found
}

例如:

echo preg_match("/\bProfessional\b/i", 'Prof'); // 0
echo preg_match("/\bProf\b/i", 'Prof');         // 1

/i 修饰符使其不区分大小写。

【讨论】:

  • 记得在$kw_to_search_for中转义/字符
  • @Ben:好建议。我添加了preg_quote
  • 防止出现“preg_match(): Unknown modifier 'G'”警告需要使用preg_quote($need_b, "/")
【解决方案2】:

就我而言,当professional.bowler 存在于句子中时,我需要完全匹配professional

preg_match('/\bprofessional\b/i', 'Im a professional.bowler'); 返回了int(1)

为了解决这个问题,我使用数组来查找使用键上的isset 的精确单词匹配。

Detection Demo

$wordList = array_flip(explode(' ', 'Im a professional.bowler'));
var_dump(isset($wordList['professional'])); //false
var_dump(isset($wordList['professional.bowler'])); //true

该方法也适用于目录路径,例如在更改 php include_path 时,而不是使用 preg_replace,这是我的特定用例。

Replacement Demo

$removePath = '/path/to/exist-not' ;
$includepath = '.' . PATH_SEPARATOR . '/path/to/exist-not' . PATH_SEPARATOR . '/path/to/exist';
$wordsPath = str_replace(PATH_SEPARATOR, ' ', $includepath);
$result = preg_replace('/\b' . preg_quote($removePath, '/'). '\b/i', '', $wordsPath);
var_dump(str_replace(' ', PATH_SEPARATOR, $result));
//".:/path/to/exist-not:/path/to/exist"

$paths = array_flip(explode(PATH_SEPARATOR, $includepath));
if(isset($paths[$removePath])){
    unset($paths[$removePath]);
}
$includepath = implode(PATH_SEPARATOR, array_flip($paths));
var_dump($includepath);
//".:/path/to/exist"

【讨论】:

    猜你喜欢
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 2016-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多