检查字符串是否包含多个单词中的任意一个

4
我正在尝试在php中创建一个单词过滤器,我找到了之前Stackoverlow的一篇帖子,其中提到以下内容以检查字符串是否包含某些单词。我想将其改编为一次性检查多个不同的单词,而无需一遍又一遍地重复代码。
$a = 'How are you ?';

if (strpos($a,'are') !== false) {
echo 'true';
}

如果我修改代码如下,它会起作用吗?......
$a = 'How are you ?';

if (strpos($a,'are' OR $a,'you' OR $a,'How') !== false) {
echo 'true';
}

“添加多个单词以进行检查的正确方法是什么?”
6个回答

8

要扩展您当前的代码,您可以使用一个目标词数组进行搜索,并使用循环:

$a = 'How are you ?';

$targets = array('How', 'are');

foreach($targets as $t)
{
    if (strpos($a,$t) !== false) {
        echo 'one of the targets was found';
        break;
    }
}

请记住,以这种方式使用strpos()意味着可以找到部分单词匹配。例如,如果目标是字符串here is an example中的ample,那么即使按定义,单词ample不存在,也会找到匹配项。
要进行整个单词匹配,请参考preg_match()文档中的示例,并通过添加循环来实现多个目标。
foreach($targets as $t)
{
    if (preg_match("/\b" . $t . "\b/i", $a)) {
        echo "A match was found.";
    } else {
        echo "A match was not found.";
    }
}

你如何添加一个不区分大小写的完整单词匹配? - Iain Simpson
@IainSimpson 请研究正则表达式,它比 strpos 更适合。 - Mark
@IainSimpson 添加了一个整词匹配的示例。 - MrCode
运行良好,但对于字符串“U.S. Army”无法正常工作 - 可能是由于点的原因。 - Kaspar L. Palgi

6

我在某个地方读到:

if(preg_match('[word1|word2]', $a)) { } 

这也将匹配'word1blabla'或'word2wrongmatch'。 - Piotr Temp

1
if (strpos($ro1['title'], $search)!==false or strpos($ro1['description'], $search)!== false or strpos($udetails['user_username'], $search)!== false)
{
//excute ur code
}

虽然这段代码片段可能解决了问题,但包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您的代码建议原因。 - andreas

0

我使用了 str_containspreg_match 两种方法来比较速度。

public static function containsMulti(?string $haystackStr, array $needlesArr): bool
{
    if ($haystackStr && $needlesArr) {
        foreach ($needlesArr as $needleStr) {
            if (str_contains($haystackStr, $needleStr)) {
                return true;
            }
        }
    }
    return false;
}

preg_match 总是比较慢(根据几个因素可能会慢2-10倍),但如果你想要进行整个单词匹配等操作,它可能会很有用。

public static function containsMulti(?string $haystackStr, array $needlesArr): bool
{
    if ($haystackStr && $needlesArr) {
        $needlesRegexStr = implode('|', array_map('preg_quote', $needlesArr));
        return (bool) preg_match('/(' . $needlesRegexStr . ')/', $haystackStr);
    }
    return false;
}

0
如果您需要一个多字节保存版本,请尝试这个。
 /**
 * Determine if a given string contains a given substring. 
 *
 * @param  string  $haystack
 * @param  string|string[]  $needles
 * @param bool $ignoreCase
 * @return bool
 */
public static function contains($haystack, $needles, $ignoreCase = false)
{
    if($ignoreCase){
        $haystack= mb_strtolower($haystack);
        $needles = array_map('mb_strtolower',$needles);
    }
    foreach ((array) $needles as $needle) {
        if ($needle !== '' && mb_strpos($haystack, $needle) !== false) {
            return true;
        }
    }

    return false;
}

虽然这段代码可能回答了问题,但提供关于它如何解决问题以及为什么解决问题的额外上下文会提高答案的长期价值。特别是为什么它比八年前被接受的答案更好。 - Sven Eberth

0

如果你有一个不太大的固定单词数量,你可以很容易地这样做:

$a = 'How are you ?';

if (strpos($a,'are') !== false || strpos($a,'you') !== false || strpos($a,'How') !== false) {
echo 'true';
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接