Answers:
您可以使用该strpos()
函数来查找另一个字符串中另一个字符串的出现:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
请注意,使用!== false
是故意的(既!= false
不会也不=== true
返回期望的结果);strpos()
返回在干草堆字符串中针串开始处的偏移量,或者false
如果找不到针则返回布尔值。由于0是有效的偏移量,而0是“假”,因此我们不能使用像这样的简单结构!strpos($a, 'are')
。
strpos($a, 'are') > -1
true 来避免此问题。从调试的角度来看,我发现我的大脑浪费了更少的时钟周期,从而确定了当我不必计算连续的等号时是否正确编写了该行。
您可以使用正则表达式,与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.
}
这是一个小的实用程序功能,在这种情况下很有用
// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
return strpos($haystack, $needle) !== false;
}
if ($email->contains("@") && $email->endsWith(".com)) { ...
或if (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
尽管大多数答案都会告诉您字符串中是否出现了子字符串,但是如果您正在寻找一个特定的单词,这通常不是您想要的,而不是substring。
有什么不同?子字符串可以出现在其他单词内:
减轻这种情况的一种方法是使用正则表达式加上单词边界(\b
):
function containsWord($str, $word)
{
return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
该方法没有上面提到的相同的误报,但确实有一些边缘情况。单词边界匹配非单词字符(\W
),这将是任何不是a-z
,A-Z
,0-9
,或_
。这意味着数字和下划线将被视为单词字符,并且这样的情况将失败:
如果您想获得比这更准确的信息,则必须开始进行英语语法解析,这是一大批蠕虫病毒(无论如何,都假定正确使用了语法,但并非总是这样)。
\b
比赛两件事情,\W
不,这使得它非常适合寻找的话在一个字符串:它匹配字符串开头的(^
)和字符串(到2005年底$
)
要确定一个字符串是否包含另一个字符串,可以使用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
具有相同的类型-即,它们都是字符串还是整数。
<?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.";
}
?>
strstr($a, 'are')
它比丑陋的优雅得多strpos($a, 'are') !== false
。PHP确实需要一个str_contains()
功能。
利用案例钝感配套使用stripos()
:
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
与SamGoody和Lego Stormtroopr同行。
如果您正在寻找一种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()
或stristr()
。
诺塔·贝内
(可选)在搜索单词之前消除冗余
从而减小索引大小并减少存储需求
更少的磁盘I / O
索引编制速度更快,因此搜索速度更快。
1.归一化
2.消除停用词
3.字典替换
用具有相同或相似含义的其他单词替换单词。(例如:用“饥饿”替换“饥饿”和“饥饿”的实例)
可以执行其他算法措施(雪球)以进一步将单词还原为其基本含义。
用十六进制等效项替换颜色名称
通过降低精度来减少数值是规范文本的其他方法。
资源
如果要避免出现“假”和“真实”问题,可以使用substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
它比strpos慢一点,但是避免了比较问题。
false
“您确定吗?” 因为位置strpos
是0
另一种选择是使用strstr()函数。就像是:
if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}
注意点:strstr()函数区分大小写。对于不区分大小写的搜索,请使用stristr()函数。
令我印象深刻的是,这里没有使用过的答案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和字符集(无借口!)的原因。
在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
根据的值选择strpos
或stripos
做工作$caseSensitive
。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)
以下功能也可以使用,并且不依赖于任何其他功能;它仅使用本机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
您可以使用以下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 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
。
$found = false
刚开始时
许多答案会substr_count
检查结果是否为>0
。但是由于该if
语句认为零与false相同,因此您可以避免执行该检查并直接编写:
if (substr_count($a, 'are')) {
要检查是否不存在,请添加!
运算符:
if (!substr_count($a, 'are')) {
可以通过三种不同的方式完成此操作:
$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
}
您应该使用不区分大小写的格式,因此,如果输入的值是in 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中发现了针。
也许您可以使用如下所示的内容:
<?php
findWord('Test all OK');
function findWord($text) {
if (strstr($text, 'ok')) {
echo 'Found a word';
}
else
{
echo 'Did not find a word';
}
}
?>
preg_match()
如果只想检查一个字符串是否包含在另一个字符串中,请不要使用。使用strpos()
或strstr()
代替,因为它们会更快。(http://in2.php.net/preg_match)
if (strpos($text, 'string_name') !== false){
echo 'get the string';
}
如果要检查字符串是否包含几个特定的单词,可以执行以下操作:
$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";
}
例如,这对于避免发送电子邮件时的垃圾邮件很有用。
strpos函数可以正常工作,但是如果您要case-insensitive
检查段落中的单词,则可以使用的stripos
功能PHP
。
例如,
$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
// Word does not exist
}
else {
// Word exists
}
查找不区分大小写的子字符串在字符串中首次出现的位置。
如果字符串中不存在该单词,则它将返回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的字符表控制,如果进行特定于语言环境的匹配,则可能会有所不同(..)