如何检查一个字符串是否包含特定的单词?

2657

考虑:

$a = 'How are you?';

if ($a contains 'are')
    echo 'true';

假设我有上述代码,正确的写法是什么样的语句if ($a contains 'are')

36个回答

37
if (preg_match('/(are)/', $a)) {
   echo 'true';
}

3
我收到了以下警告:WARNING preg_match(): Delimiter must not be alphanumeric or backslash - Pathros

32

另一种选择是使用strstr()函数,大致如下:

if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}

需要注意的是:strstr()函数区分大小写。如果要进行不区分大小写的搜索,请使用stristr()函数。


1
如果未找到 needle,则 strstr() 返回 FALSE。因此,不需要 strlen。 - AKS

30

我有点惊讶,这里使用了 strposstrstr 和类似函数的答案都没有提到 多字节字符串函数(2015-05-08)。

基本上,如果你在查找具有某些语言特定字符(如德语、法语、葡萄牙语、西班牙语等)的单词时遇到困难(例如:äéôçºñ),你可能需要在函数前加上 mb_。因此,接受的答案将使用 mb_strposmb_stripos(用于不区分大小写的匹配):

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

如果你无法保证所有数据都是100%的UTF-8编码, 你可能需要使用mb_函数。
一篇很好的文章,可以帮助你理解为什么要使用Unicode和字符集(没有借口!)是由Joel Spolsky撰写的The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets

30

在PHP中,验证字符串是否包含某个子串的最佳方法是使用一个简单的帮助函数,如下所示:

function contains($haystack, $needle, $caseSensitive = false) {
    return $caseSensitive ?
            (strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
            (stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}

说明:

  • strpos 查找字符串中第一次出现的区分大小写的子字符串的位置。
  • stripos 查找字符串中第一次出现的不区分大小写的子字符串的位置。
  • myFunction($haystack, $needle) === FALSE ? FALSE : TRUE 确保 myFunction 始终返回布尔值,并修复了当子字符串的索引为0时出现的意外行为。
  • $caseSensitive ? A : B 根据 $caseSensitive 的值选择使用 strposstripos 进行操作。

输出:

var_dump(contains('bare','are'));            // Outputs: bool(true)
var_dump(contains('stare', 'are'));          // Outputs: bool(true)
var_dump(contains('stare', 'Are'));          // Outputs: bool(true)
var_dump(contains('stare', 'Are', true));    // Outputs: bool(false)
var_dump(contains('hair', 'are'));           // Outputs: bool(false)
var_dump(contains('aren\'t', 'are'));        // Outputs: bool(true)
var_dump(contains('Aren\'t', 'are'));        // Outputs: bool(true)
var_dump(contains('Aren\'t', 'are', true));  // Outputs: bool(false)
var_dump(contains('aren\'t', 'Are'));        // Outputs: bool(true)
var_dump(contains('aren\'t', 'Are', true));  // Outputs: bool(false)
var_dump(contains('broad', 'are'));          // Outputs: bool(false)
var_dump(contains('border', 'are'));         // Outputs: bool(false)

27

您可以使用strstr函数:

$haystack = "I know programming";
$needle   = "know";
$flag = strstr($haystack, $needle);

if ($flag){

    echo "true";
}

不使用内置函数:

$haystack  = "hello world";
$needle = "llo";

$i = $j = 0;

while (isset($needle[$i])) {
    while (isset($haystack[$j]) && ($needle[$i] != $haystack[$j])) {
        $j++;
        $i = 0;
    }
    if (!isset($haystack[$j])) {
        break;
    }
    $i++;
    $j++;

}
if (!isset($needle[$i])) {
    echo "YES";
}
else{
    echo "NO ";
}

3
如果你搜索第一个单词,会导致程序崩溃。 - T30

25

许多使用substr_count的答案会检查结果是否>0。但是由于if语句将零视为false的同义词,因此您可以避免该检查并直接编写:

if (substr_count($a, 'are')) {

要检查是否出现,请添加!运算符:

Translated:

为了检查是否未出现,请添加!运算符:

if (!substr_count($a, 'are')) {

嗯...部分正确,在php中,0 == false为真,但0 === false为假。 - Andrejs Gubars

25
下面的函数也可以工作,不依赖于任何其他函数;它仅使用本机PHP字符串操作。个人认为不建议使用此方法,但您可以看到它是如何工作的:
<?php

if (!function_exists('is_str_contain')) {
  function is_str_contain($string, $keyword)
  {
    if (empty($string) || empty($keyword)) return false;
    $keyword_first_char = $keyword[0];
    $keyword_length = strlen($keyword);
    $string_length = strlen($string);

    // case 1
    if ($string_length < $keyword_length) return false;

    // case 2
    if ($string_length == $keyword_length) {
      if ($string == $keyword) return true;
      else return false;
    }

    // case 3
    if ($keyword_length == 1) {
      for ($i = 0; $i < $string_length; $i++) {

        // Check if keyword's first char == string's first char
        if ($keyword_first_char == $string[$i]) {
          return true;
        }
      }
    }

    // case 4
    if ($keyword_length > 1) {
      for ($i = 0; $i < $string_length; $i++) {
        /*
        the remaining part of the string is equal or greater than the keyword
        */
        if (($string_length + 1 - $i) >= $keyword_length) {

          // Check if keyword's first char == string's first char
          if ($keyword_first_char == $string[$i]) {
            $match = 1;
            for ($j = 1; $j < $keyword_length; $j++) {
              if (($i + $j < $string_length) && $keyword[$j] == $string[$i + $j]) {
                $match++;
              }
              else {
                return false;
              }
            }

            if ($match == $keyword_length) {
              return true;
            }

            // end if first match found
          }

          // end if remaining part
        }
        else {
          return false;
        }

        // end for loop
      }

      // end case4
    }

    return false;
  }
}

测试:

var_dump(is_str_contain("test", "t")); //true
var_dump(is_str_contain("test", "")); //false
var_dump(is_str_contain("test", "test")); //true
var_dump(is_str_contain("test", "testa")); //flase
var_dump(is_str_contain("a----z", "a")); //true
var_dump(is_str_contain("a----z", "z")); //true 
var_dump(is_str_contain("mystringss", "strings")); //true 

14
请问为什么你会使用这样的函数,当strpos已经足够可行了呢? - sg3s
3
@sg3s: 你说得完全正确,但是strpos也基于类似的东西,而且我发帖并不是为了声望,只是想分享一点知识。 - Jason OOO
最后一个 var_dump 是 false。 - Sunny
1
@Sunny:这是一个笔误:var_dump(is_str_contain("mystringss", "strings")); //true - Jason OOO

23

我曾经遇到过一些问题,最后我选择创建自己的解决方案。这个方案不使用正则表达式引擎:

function contains($text, $word)
{
    $found = false;
    $spaceArray = explode(' ', $text);

    $nonBreakingSpaceArray = explode(chr(160), $text);

    if (in_array($word, $spaceArray) ||
        in_array($word, $nonBreakingSpaceArray)
       ) {

        $found = true;
    }
    return $found;
 }

您可能会注意到,先前的解决方案并不适用于将单词用作另一个单词的前缀。为了使用您的示例:

$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";

通过上述样例,$a$b 都包含 $c,但你可能希望你的函数告诉你只有 $a 包含 $c


1
你可能是想在开头写成 $found = false - slownage
1
如果单词与逗号、问号或句点相连,您的函数可能无法正常工作。例如,“你看到的就是你得到的。”,而您想确定句子中是否有“得到”一词。请注意“得到”旁边的句号。在这种情况下,您的函数将返回false。建议使用正则表达式或substr(我认为它无论如何都使用正则表达式)来搜索/替换字符串。 - lightbringer
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Decebal
这个答案演示不足,且在许多扩展场景下都失败了。我看不到采用这种技术的任何好处。这里是优化后的自定义函数和迭代调用链接:https://3v4l.org/E9dfD 我不想编辑这个维基,因为我认为这是浪费研究人员时间。 - mickmackusa

21

使用strstr()stristr()函数在字符串中查找单词的另一种方法如下:

<?php
    $a = 'How are you?';
    if (strstr($a,'are'))  // Case sensitive
        echo 'true';
    if (stristr($a,'are'))  // Case insensitive
        echo 'true';
?>

这是相反的。stristr中的i代表不区分大小写。 - Adam Merrifield

19

有三种不同的方式可以实现:

 $a = 'How are you?';

1- stristr()

 if (strlen(stristr($a,"are"))>0) {
    echo "true"; // are Found
 } 

2- strpos()

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

3- preg_match()

 if( preg_match("are",$a) === 1) {
   echo "true"; // are Found
 }

好的,但preg_match存在风险,因为它可能返回false或0。在#3中,你应该测试是否===1。 - Shapeshifter

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