考虑:

$a = 'How are you?';

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

假设我有上面的代码,如果($a包含“are”),写语句的正确方法是什么?


当前回答

Use:

$text = 'This is a test';
echo substr_count($text, 'is'); // 2

// So if you want to check if is exists in the text just put
// in a condition like this:
if (substr_count($text, 'is') > 0) {
    echo "is exists";
}

其他回答

参考SamGoody和Lego Stormtropr的评论。

如果您正在寻找基于多个单词的接近度/相关性对搜索结果进行排名的PHP算法这里有一种仅使用PHP生成搜索结果的快速简便方法:

其他布尔搜索方法(如strpos()、preg_match()、strstr()或stristr(

无法搜索多个单词结果未排名

基于向量空间模型和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()或stritr()。

不可接受的

可选地,在搜索单词之前消除冗余

从而减少索引大小并减少存储需求更少的磁盘I/O更快的索引和因此更快的搜索。

1.标准化

将所有文本转换为小写

2.停止字消除

从文本中删除没有实际意义的单词(如“and”、“or”、“the”、“for”等)

3.字典替换

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

资源

http://linuxgazette.net/164/sephton.htmlhttp://snowball.tartarus.org/MySQL全文搜索分数说明http://dev.mysql.com/doc/internals/en/full-text-search.htmlhttp://en.wikipedia.org/wiki/Vector_space_modelhttp://en.wikipedia.org/wiki/Tf%E2%80%93idfhttp://phpir.com/simple-search-the-vector-space-model/

Use:

$text = 'This is a test';
echo substr_count($text, 'is'); // 2

// So if you want to check if is exists in the text just put
// in a condition like this:
if (substr_count($text, 'is') > 0) {
    echo "is exists";
}

您可以使用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 ";
}

可以使用以下函数检查字符串:

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

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

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

执行此操作并指定分隔符的一种方法是使用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的字符控制表,如果正在进行特定于区域设置的匹配,则可能会有所不同(..)