天天看点

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

考虑:

$a = 'How are you?';

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

假设我有上面的代码,

if ($a contains 'are')

,写语句的正确方法

if ($a contains 'are')

什么?

#1楼

另一种选择是使用strstr()函数。 就像是:

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

注意点:strstr()函数区分大小写。 对于不区分大小写的搜索,请使用stristr()函数。

#2楼

如果要避免出现“假”和“真实”问题,可以使用substr_count:

if (substr_count($a, 'are') > 0) {
    echo "at least one 'are' is present!";
}
           

它比strpos慢一点,但是避免了比较问题。

#3楼

以下功能也可以使用,并且不依赖于任何其他功能; 它仅使用本机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 
           

#4楼

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

#5楼

通过

stripos()

使用不区分大小写的匹配 :

if (stripos($string,$stringToSearch) !== false) {
    echo 'true';
}
           

#6楼

使用strstr()和stristr()从字符串中查找单词出现的另一种选择如下:

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

#7楼

我对此有些麻烦,最后我选择创建自己的解决方案。 不使用正则表达式引擎:

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

#8楼

如果只想检查一个字符串是否包含在另一个字符串中,请不要使用

preg_match()

。 请改用

strpos()

strstr()

因为它们会更快。 ( http://in2.php.net/preg_match )

if (strpos($text, 'string_name') !== false){
   echo 'get the string';
}
           

#9楼

尽管大多数答案都会告诉您字符串中是否出现了子字符串,但是如果您正在寻找一个特定的单词 ,那通常不是您想要的,而不是substring 。

有什么不同? 子字符串可以出现在其他单词内:

  • “区域”开头的“区域”
  • “野兔”末尾的“是”
  • “票价”中间的“是”

减轻这种情况的一种方法是使用带有单词边界 (

\\b

)的正则表达式:

function containsWord($str, $word)
{
    return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
           

该方法没有上面提到的相同的误报,但确实有一些边缘情况。 单词边界与非单词字符(

\\W

)匹配,这些字符将不是

az

AZ

0-9

_

任何字符。 这意味着数字和下划线将被视为单词字符,并且这样的情况将失败:

  • “您在想什么”中的“是”。
  • “大声笑,那些是4”中的“是”吗?

如果您想获得比这更准确的信息,则必须开始进行英语语法解析,这是一大堆蠕虫(并且无论如何都假定正确使用了语法,但并非总是这样)。

#10楼

与SamGoody和Lego Stormtroopr同行。

如果您正在寻找一种PHP算法来根据多个单词的接近度/相关性对搜索结果进行排名 ,那么这里提供了一种仅使用PHP即可生成搜索结果的快捷方法:

其他布尔搜索方法(例如

strpos()

preg_match()

strstr()

stristr()

  1. 无法搜索多个单词
  2. 结果排名

基于矢量空间模型和tf-idf(项频率-文档反向频率)的 PHP方法:

听起来很困难,但非常容易。

如果要在一个字符串中搜索多个单词,核心问题是如何为每个单词分配权重?

如果我们可以根据术语在整个字符串中的代表性来对字符串中的术语进行加权,则可以按照与查询最匹配的结果对结果进行排序。

这是向量空间模型的思想,与SQL全文搜索的工作原理相距不远:

function get_corpus_index($corpus = array(), $separator=' ') {

    $dictionary = array();

    $doc_count = array();

    foreach($corpus as $doc_id => $doc) {

        $terms = explode($separator, $doc);

        $doc_count[$doc_id] = count($terms);

        // tf–idf, short for term frequency–inverse document frequency, 
        // according to wikipedia is a numerical statistic that is intended to reflect 
        // how important a word is to a document in a corpus

        foreach($terms as $term) {

            if(!isset($dictionary[$term])) {

                $dictionary[$term] = array('document_frequency' => 0, 'postings' => array());
            }
            if(!isset($dictionary[$term]['postings'][$doc_id])) {

                $dictionary[$term]['document_frequency']++;

                $dictionary[$term]['postings'][$doc_id] = array('term_frequency' => 0);
            }

            $dictionary[$term]['postings'][$doc_id]['term_frequency']++;
        }

        //from http://phpir.com/simple-search-the-vector-space-model/

    }

    return array('doc_count' => $doc_count, 'dictionary' => $dictionary);
}

function get_similar_documents($query='', $corpus=array(), $separator=' '){

    $similar_documents=array();

    if($query!=''&&!empty($corpus)){

        $words=explode($separator,$query);

        $corpus=get_corpus_index($corpus, $separator);

        $doc_count=count($corpus['doc_count']);

        foreach($words as $word) {

            if(isset($corpus['dictionary'][$word])){

                $entry = $corpus['dictionary'][$word];


                foreach($entry['postings'] as $doc_id => $posting) {

                    //get term frequency–inverse document frequency
                    $score=$posting['term_frequency'] * log($doc_count + 1 / $entry['document_frequency'] + 1, 2);

                    if(isset($similar_documents[$doc_id])){

                        $similar_documents[$doc_id]+=$score;

                    }
                    else{

                        $similar_documents[$doc_id]=$score;

                    }
                }
            }
        }

        // length normalise
        foreach($similar_documents as $doc_id => $score) {

            $similar_documents[$doc_id] = $score/$corpus['doc_count'][$doc_id];

        }

        // sort from  high to low

        arsort($similar_documents);

    }   

    return $similar_documents;
}
           

情况1

$query = 'are';

$corpus = array(
    1 => 'How are you?',
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';
           

结果

Array
(
    [1] => 0.52832083357372
)
           

案例2

$query = 'are';

$corpus = array(
    1 => 'how are you today?',
    2 => 'how do you do',
    3 => 'here you are! how are you? Are we done yet?'
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';
           

结果

Array
(
    [1] => 0.54248125036058
    [3] => 0.21699250014423
)
           

情况3

$query = 'we are done';

$corpus = array(
    1 => 'how are you today?',
    2 => 'how do you do',
    3 => 'here you are! how are you? Are we done yet?'
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';
           

结果

Array
(
    [3] => 0.6813781191217
    [1] => 0.54248125036058
)
           

尚有许多改进,但是该模型提供了一种从自然查询中获得良好结果的方法,这些自然查询没有布尔运算符,例如

strpos()

preg_match()

strstr()

stristr()

诺塔·贝内

(可选)在搜索单词之前消除冗余

  • 从而减小索引大小并减少存储需求
  • 更少的磁盘I / O
  • 索引编制速度更快,因此搜索速度更快。

1.归一化

  • 将所有文本转换为小写

2.消除停用词

  • 从文本中消除没有实际含义的单词(例如“和”,“或”,“该”,“用于”等)

3.字典替换

  • 用具有相同或相似含义的其他单词替换单词。 (例如:用“饥饿”替换“饥饿”和“饥饿”的实例)
  • 可以执行其他算法措施(雪球)以进一步将单词还原为其基本含义。
  • 用十六进制等效项替换颜色名称
  • 通过降低精度来减少数值是规范文本的其他方法。

资源

  • http://linuxgazette.net/164/sephton.html
  • http://snowball.tartarus.org/
  • MySQL全文搜索分数解释
  • http://dev.mysql.com/doc/internals/en/full-text-search.html
  • http://en.wikipedia.org/wiki/Vector_space_model
  • http://en.wikipedia.org/wiki/Tf%E2%80%93idf
  • http://phpir.com/simple-search-the-vector-space-model/

#11楼

您需要使用相同/不相同的运算符,因为strpos可以返回0作为其索引值。 如果您喜欢三元运算符,请考虑使用以下内容(我承认这有点倒退):

echo FALSE === strpos($a,'are') ? 'false': 'true';
           

#12楼

您应该使用不区分大小写的格式,因此,如果输入的值

small

caps

则不要紧。

<?php
$grass = "This is pratik joshi";
$needle = "pratik";
if (stripos($grass,$needle) !== false) { 

 /*If i EXCLUDE : !== false then if string is found at 0th location, 
   still it will say STRING NOT FOUND as it will return '0' and it      
   will goto else and will say NOT Found though it is found at 0th location.*/
    echo 'Contains word';
}else{
    echo "does NOT contain word";
}
?>
           

在这里,stripos在不考虑大小写(小/大写)的情况下,在heystack中发现了针。

PHPCode示例与输出

#13楼

简写

$result = false!==strpos($a, 'are');
           

#14楼

也许您可以使用如下所示的内容:

<?php
    findWord('Test all OK');

    function findWord($text) {
        if (strstr($text, 'ok')) {
            echo 'Found a word';
        }
        else
        {
            echo 'Did not find a word';
        }
    }
?>
           

#15楼

为了找到一个“单词”,而不是出现实际上可能是另一个单词的一部分的一系列字母,下面将是一个很好的解决方案。

$string = 'How are you?';
$array = explode(" ", $string);

if (in_array('are', $array) ) {
    echo 'Found the word';
}
           

#16楼

令我印象深刻的是,这里没有使用

strpos

strstr

和类似函数的答案提到多字节字符串函数 (2015-05-08)。

基本上,如果您在查找带有某些语言特定字符的单词时遇到麻烦 ,例如德语,法语,葡萄牙语,西班牙语等(例如: ä , é , ô , ç , º , ñ ),则可能要优先使用

mb_

的功能。 因此,可接受的答案将使用

mb_strpos

mb_stripos

(用于不区分大小写的匹配):

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

如果您不能保证所有数据都是UTF-8格式的100% ,则可能要使用

mb_

函数。

很好的一篇文章,为什么Joel Spolsky解释了为什么绝对是每个软件开发人员绝对绝对肯定了解Unicode和字符集(无借口!)的原因。

#17楼

strpos函数可以正常工作,但是如果您要对段落中的单词进行

case-insensitive

检查,则可以使用

PHP

stripos

函数。

例如,

$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
    // Word does not exist
}
else {
    // Word exists
}
           

查找不区分大小写的子字符串在字符串中首次出现的位置。

如果字符串中不存在该单词,则它将返回false,否则它将返回该单词的位置。

#18楼

您可以使用

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 ";
}
           

#19楼

检查字符串是否包含特定单词?

这意味着字符串必须解析为单词(请参见下面的注释)。

一种执行此操作并指定分隔符的方法是使用

preg_split

( doc ):

<?php

function contains_word($str, $word) {
  // split string into words
  // separators are substrings of at least one non-word character
  $arr = preg_split('/\W+/', $str, NULL, PREG_SPLIT_NO_EMPTY);

  // now the words can be examined each
  foreach ($arr as $value) {
    if ($value === $word) {
      return true;
    }
  }
  return false;
}

function test($str, $word) {
  if (contains_word($str, $word)) {
    echo "string '" . $str . "' contains word '" . $word . "'\n";
  } else {
    echo "string '" . $str . "' does not contain word '" . $word . "'\n" ;
  }
}

$a = 'How are you?';

test($a, 'are');
test($a, 'ar');
test($a, 'hare');

?>
                

奔跑给

$ php -f test.php                   
string 'How are you?' contains word 'are' 
string 'How are you?' does not contain word 'ar'
string 'How are you?' does not contain word 'hare'
           

注意:这里我们并不是指每个符号序列的单词。

单词的实际定义在某种意义上是PCRE正则表达式引擎,其中单词是仅由单词字符组成的子字符串,由非单词字符分隔。

“单词”字符是任何字母或数字或下划线字符,即可以成为Perl“单词”一部分的任何字符。 字母和数字的定义由PCRE的字符表控制,如果进行特定于语言环境的匹配,则可能会有所不同(..)

#20楼

如果要检查字符串是否包含几个特定的​​单词,可以执行以下操作:

$badWords = array("dette", "capitale", "rembourser", "ivoire", "mandat");

$string = "a string with the word ivoire";

$matchFound = preg_match_all("/\b(" . implode($badWords,"|") . ")\b/i", $string, $matches);

if ($matchFound) {
    echo "a bad word has been found";
}
else {
    echo "your string is okay";
}
           

例如,这对于避免发送电子邮件时的垃圾邮件很有用。

#21楼

可以使用以下功能检查字符串:

function either_String_existor_not($str, $character) {
    if (strpos($str, $character) !== false) {
        return true;
    }
    return false;
}
           

#22楼

可以通过三种不同的方式完成此操作:

$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
 }
           

#23楼

在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($haystack, $needle) === FALSE ? FALSE : TRUE

    确保

    myFunction

    始终返回布尔值,并在子字符串的索引为0时修复意外行为。
  • $caseSensitive ? A : B

    $caseSensitive ? A : B

    根据

    $caseSensitive

    的值选择

    strpos

    stripos

    进行工作。

输出:

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)
           

#24楼

许多使用

substr_count

的答案检查结果是否为

>0

。 但是由于

if

语句认为零与false相同 ,因此您可以避免执行该检查并直接编写:

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

要检查是否不存在,请添加

!

操作员:

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

#25楼

您可以使用正则表达式,与其他用户提到的

strpos

相比,它在单词匹配方面更好,而且对于诸如票价,护理,凝视等字符串也将返回true。这可以通过使用单词边界在正则表达式中简单地避免。

一个简单的匹配are可能看起来像这样:

$a = 'How are you?';

if (preg_match('/\bare\b/', $a)) {
    echo 'true';
}
           

在性能方面,

strpos

大约快三倍,并且要记住,当我一次进行一百万次比较时,

preg_match

1.5秒完成,而

strpos

用了0.5秒。

编辑:为了搜索字符串的任何部分,而不仅仅是逐个单词,我建议使用正则表达式,例如

$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
    echo 'true';
}
           

正则表达式末尾的

i

将正则表达式更改为不区分大小写,如果不希望这样,可以将其省略。

现在,在某些情况下这可能会很成问题,因为$ search字符串没有以任何方式进行消毒,我的意思是,在某些情况下,它可能无法通过检查,就像

$search

是用户输入一样,他们可以添加一些可能表现得像一些不同的正则表达式...

另外,这是一个测试和查看各种正则表达式Regex101的好工具

要将这两组功能组合为一个多功能(包括具有区分大小写的功能),可以使用以下代码:

function FindString($needle,$haystack,$i,$word)
{   // $i should be "" or "i" for case insensitive
    if (strtoupper($word)=="W")
    {   // if $word is "W" then word search instead of string in string search.
        if (preg_match("/\b{$needle}\b/{$i}", $haystack)) 
        {
            return true;
        }
    }
    else
    {
        if(preg_match("/{$needle}/{$i}", $haystack)) 
        {
            return true;
        }
    }
    return false;
    // Put quotes around true and false above to return them as strings instead of as bools/ints.
}
           

#26楼

您可以使用

strpos()

函数来查找另一个字符串中另一个字符串的出现:

$a = 'How are you?';

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

注意,

!== false

的使用是有意的(

!= false

=== true

都不会返回期望的结果)。

strpos()

返回大海捞针字符串中针串开始的偏移量,或者如果找不到针,则返回布尔值

false

。 由于0是一个有效的偏移量,而0是“ falsey”,我们不能使用更简单的结构,例如

!strpos($a, 'are')

#27楼

看一下

strpos()

<?php
    $mystring = 'abc';
    $findme   = 'a';
    $pos = strpos($mystring, $findme);

    // Note our use of ===. Simply, == would not work as expected
    // because the position of 'a' was the 0th (first) character.
    if ($pos === false) {
        echo "The string '$findme' was not found in the string '$mystring'.";
    }
    else {
        echo "The string '$findme' was found in the string '$mystring',";
        echo " and exists at position $pos.";
    }
?>
           

#28楼

要确定一个字符串是否包含另一个字符串,可以使用PHP函数strpos() 。

int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )

<?php

$haystack = 'how are you';
$needle = 'are';

if (strpos($haystack,$needle) !== false) {
    echo "$haystack contains $needle";
}

?>
           

警告:

如果您要搜索的针头位于干草堆的开头,它将返回位置0,如果执行

==

比较不起作用,则需要执行

===

==

符号是一个比较,用于测试左侧的变量/表达式/常量是否与右侧的变量/表达式/常量具有相同的值。

===

符号是一个比较,以查看两个变量/表达式/常量是否相等

AND

具有相同的类型-即,两个都是字符串还是两个都是整数。

#29楼

如果您的搜索不区分大小写,则使用

strstr()

stristr()

是另一种选择。

#30楼

这是一个小的实用程序功能,在这种情况下很有用

// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
    return strpos($haystack, $needle) !== false;
}