首先,我想告诉大家,我需要的是in_array PHP函数的反向。
我需要搜索字符串中数组的所有项,如果找到任何项,函数将返回true,否则返回false。
我需要这个问题的最快解决方案,当然这可以通过迭代数组和使用strpos函数来成功。
欢迎提出任何建议。
示例数据:
$string = 'Alice goes to school every day';
$searchWords = array('basket','school','tree');
返回true
$string = 'Alice goes to school every day';
$searchWords = array('basket','cat','tree');
returnfalse
您应该尝试使用preg_match:
if (preg_match('/' . implode('|', $searchWords) . '/', $string)) return true;
在这里发表了一些评论之后,一个正确逃脱的解决方案:
function contains($string, Array $search, $caseInsensitive = false) {
$exp = '/'
. implode('|', array_map('preg_quote', $search))
. ($caseInsensitive ? '/i' : '/');
return preg_match($exp, $string) ? true : false;
}
function searchWords($string,$words)
{
foreach($words as $word)
{
if(stristr($string," " . $word . " ")) //spaces either side to force a word
{
return true;
}
}
return false;
}
用法:
$string = 'Alice goes to school every day';
$searchWords = array('basket','cat','tree');
if(searchWords($string,$searchWords))
{
//matches
}
还要注意,函数stristr用于使其不区分大小写的
按照malko的例子,但要正确转义值。
function contains( $string, array $search ) {
return 0 !== preg_match(
'/' . implode( '|', preg_quote( $search, '/' ) ) . '/',
$string
);
}
如果字符串可以使用空格进行分解,则如下所示:
var_dump(array_intersect(explode(' ', $str), $searchWords) != null);
OUTPUT:对于您提供的两个示例:
bool(true)
bool(false)
更新:
如果字符串不能使用空格字符进行分解,那么使用这样的代码来拆分任何词尾字符上的字符串:
var_dump(array_intersect(preg_split('~'b~', $str), $searchWords) != null);
关于什么更快总是有争论,所以我想我应该使用不同的方法运行一些测试。
测试运行:
- strpos
- 带有foreach循环的preg_match
- 使用regex或preg_match
- 带要分解的字符串的索引搜索
- 索引搜索为数组(字符串已分解)
运行两组测试。一个在大文本文档(114350字)上,另一个在小文本文档(120字)上。在每组中,所有测试都运行100次,然后取平均值。测试并没有忽略这个案例,这样做会让它们都更快。搜索索引的测试已预先编制索引。我自己编写了索引代码,我相信效率较低,但大文件的索引需要17.92秒,小文件的索引则需要0.001秒。
搜索的术语包括:gazerbeam(未在文档中找到)、legal(在文档中发现)和target(未在文件中找到)。
以秒为单位完成单个测试的结果,按速度排序:
大文件:
- 0.0000455808639526(无爆炸指数)
- 0.0009979915618897(使用regex或的preg_match)
- 0.00116724164734(strpos)
- 0.00223632574081421(使用foreach循环的preg_match)
- 0.0051533532142639(带爆炸的索引)
小文件
- 0.000003724098205566(strpos)
- 0.000005958080291748(使用regex或的preg_match)
- 0.000012607574462891(使用foreach循环进行预匹配)
- 0.000021204948425293(指数无爆炸)
- 0.000060625076293945(带爆炸指数)
请注意,对于小文件,strpos比preg_match(使用regex或)更快,但对于大文件,速度较慢。其他因素,例如搜索词的数量,当然会影响这一点。
使用的算法:
//strpos
$str = file_get_contents('text.txt');
$t = microtime(true);
foreach ($search as $word) if (strpos($str, $word)) break;
$strpos += microtime(true) - $t;
//preg_match
$str = file_get_contents('text.txt');
$t = microtime(true);
foreach ($search as $word) if (preg_match('/' . preg_quote($word) . '/', $str)) break;
$pregmatch += microtime(true) - $t;
//preg_match (regex or)
$str = file_get_contents('text.txt');
$orstr = preg_quote(implode('|', $search));
$t = microtime(true);
if preg_match('/' . $orstr . '/', $str) {};
$pregmatchor += microtime(true) - $t;
//index with explode
$str = file_get_contents('textindex.txt');
$t = microtime(true);
$ar = explode(" ", $str);
foreach ($search as $word) {
$start = 0;
$end = count($ar);
do {
$diff = $end - $start;
$pos = floor($diff / 2) + $start;
$temp = $ar[$pos];
if ($word < $temp) {
$end = $pos;
} elseif ($word > $temp) {
$start = $pos + 1;
} elseif ($temp == $word) {
$found = 'true';
break;
}
} while ($diff > 0);
}
$indexwith += microtime(true) - $t;
//index without explode (already in array)
$str = file_get_contents('textindex.txt');
$found = 'false';
$ar = explode(" ", $str);
$t = microtime(true);
foreach ($search as $word) {
$start = 0;
$end = count($ar);
do {
$diff = $end - $start;
$pos = floor($diff / 2) + $start;
$temp = $ar[$pos];
if ($word < $temp) {
$end = $pos;
} elseif ($word > $temp) {
$start = $pos + 1;
} elseif ($temp == $word) {
$found = 'true';
break;
}
} while ($diff > 0);
}
$indexwithout += microtime(true) - $t;
试试这个:
$string = 'Alice goes to school every day';
$words = split(" ", $string);
$searchWords = array('basket','school','tree');
for($x = 0,$l = count($words); $x < $l;) {
if(in_array($words[$x++], $searchWords)) {
//....
}
}
下面打印从字符串中的数组中找到的元素数量的频率
function inString($str, $arr, $matches=false)
{
$str = explode(" ", $str);
$c = 0;
for($i = 0; $i<count($str); $i++)
{
if(in_array($str[$i], $arr) )
{$c++;if($matches == false)break;}
}
return $c;
}
下面的链接将帮助您:只需要根据需要进行自定义。
检查字符串中是否存在数组元素
自定义:
function result_arrayInString($prdterms,208){
if(arrayInString($prdterms,208)){
return true;
}else{
return false;
}
}
这可能对你有帮助。