考虑:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
假设我有上面的代码,编写语句的正确方法是什么 if ($a contains 'are')
?
考虑:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
假设我有上面的代码,编写语句的正确方法是什么 if ($a contains 'are')
?
你可以使用 strpos()
用于在另一个字符串中查找一个字符串的出现的函数:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
注意使用 !== false
是刻意的; strpos()
返回针字符串在haystack字符串中开始的偏移量或布尔值 false
如果找不到针头。由于0是有效偏移量而0是“假”,因此我们不能使用更简单的结构 !strpos($a, 'are')
。
你可以使用 strpos()
用于在另一个字符串中查找一个字符串的出现的函数:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
注意使用 !== false
是刻意的; strpos()
返回针字符串在haystack字符串中开始的偏移量或布尔值 false
如果找不到针头。由于0是有效偏移量而0是“假”,因此我们不能使用更简单的结构 !strpos($a, 'are')
。
您可以使用正则表达式,与其他用户提到的strpos相比,它更适合单词匹配,对于诸如票价,关心,凝视等字符串,它也会返回true。这可以通过使用单词边界在正则表达式中简单地避免。
一个简单的匹配可能看起来像这样:
$a = 'How are you?';
if (preg_match('/\bare\b/',$a))
echo 'true';
在性能方面,strpos的速度提高了大约三倍,并且考虑到,当我同时进行一百万次比较时,它需要1.5分钟的预匹配,并且需要花费0.5秒。
这是一个小实用函数,在这种情况下很有用
// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
return strpos($haystack, $needle) !== false;
}
虽然这些答案中的大部分都会告诉您字符串中是否出现子字符串,但如果您正在寻找特定字符串,那通常不是您想要的 字,而不是 子。
有什么不同?子字符串可以出现在其他词语中:
减轻这种情况的一种方法是使用与之相配的正则表达式 字边界 (\b
):
function containsWord($str, $word)
{
return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
这种方法没有上面提到的相同的误报,但它确实有一些自己的边缘情况。单词边界匹配非单词字符(\W
),这将是任何不是 a-z
, A-Z
, 0-9
, 要么 _
。这意味着数字和下划线将被计为单词字符,这样的场景将失败:
如果你想要比这更准确的东西,你将不得不开始进行英语语法语法分析,这是一个非常大的蠕虫(并假设正确使用语法,无论如何,这并不总是给定)。
要确定字符串是否包含另一个字符串,您可以使用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,如果您执行了此操作 ==
比较那不起作用,你需要做一个 ===
一个 ==
sign是一个比较,并测试左边的变量/ expression / constant是否与右边的变量/ expression / constant具有相同的值。
一个 ===
sign是比较两个变量/ expresions / constants是否相等 AND
具有相同的类型 - 即两者都是字符串或两者都是整数。
<?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.";
}
?>
如果你想避免“假”和“真理”问题,你可以使用substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
它比strpos慢一点,但它避免了比较问题。
利用 不区分大小写 运用 stripos()
:
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
同意SamGoody和Lego Stormtroopr的评论。
如果您正在寻找PHP算法 根据邻近度/相关性对搜索结果进行排名 多个单词 这里提供了一种仅使用PHP生成搜索结果的快捷方法:
其他布尔搜索方法的问题,如 strpos()
, preg_match()
, strstr()
要么 stristr()
基于PHP的PHP方法 矢量空间模型 和 tf-idf(术语频率 - 逆文档频率):
这听起来很难,但却非常容易。
如果我们想在字符串中搜索多个单词,核心问题是我们如何为每个单词分配权重?
如果我们可以根据它们对字符串整体的代表性来对字符串中的术语进行加权, 我们可以通过最符合查询的结果来排序结果。
这是矢量空间模型的概念, 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()
。
NOTA BENE
可选地在搜索单词之前消除冗余
从而减小了索引大小并减少了存储需求
减少磁盘I / O.
更快的索引和更快的搜索。
1.规范化
2.删除词汇
3.字典替换
将词语替换为具有相同或相似含义的其他词语。 (例如:用'饥饿'代替'饥饿'和'饥饿'的例子)
可以执行进一步的算法测量(滚雪球)以进一步将单词减少到其本质含义。
用十六进制等值替换颜色名称
通过降低精度来减少数值是标准化文本的其他方法。
资源