How do I check if a string contains a specific word?
考虑:
1 2 3 4 | $a = 'How are you?'; if ($a contains 'are') echo 'true'; |
假设我有上面的代码,那么正确地编写语句
您可以使用
1 2 3 4 5 |
注意,使用
您可以使用正则表达式,与其他用户提到的strpos相比,单词匹配更好,它还将为字符串(如fare、care、stare等)返回true。在正则表达式中,使用单词边界可以简单地避免这种情况。
ARE的简单匹配可以如下所示:
1 2 3 4 5 |
在性能方面,strpos大约快了三倍,我考虑到,当我一次做了一百万个比较时,它需要
编辑:为了搜索字符串的任何部分,而不仅仅是逐字搜索,我建议使用
1 2 3 4 5 |
正则表达式末尾的
现在,这在某些情况下可能会有很大的问题,因为$search字符串在任何情况下都不会被清除,我的意思是,在某些情况下,它可能不会通过检查,就好像
此外,这里还有一个测试和查看各种正则表达式regex101解释的好工具
要将这两组功能组合成一个多用途功能(包括可选的区分大小写),您可以使用如下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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. } |
这里有一个小的实用函数,在这种情况下很有用
1 2 3 4 5 | // returns true if $needle is a substring of $haystack function contains($needle, $haystack) { return strpos($haystack, $needle) !== false; } |
虽然这些答案中的大多数都会告诉你字符串中是否出现了子字符串,但如果你在寻找一个特定的单词,而不是子字符串,通常就不是你想要的。
有什么区别?子字符串可以出现在其他单词中:
- "区域"开头的"are"
- "兔子"结尾的"是"
- "是"在"票价"中间
减轻这种情况的一种方法是使用一个与单词边界相结合的正则表达式(
1 2 3 4 | function containsWord($str, $word) { return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str); } |
这种方法没有上面提到的相同的假阳性,但它也有自己的一些边缘情况。单词边界在非单词字符(
- 你在想什么?
- 在"lol u dunno wut these are4?"中的"are"?
如果你想要比这更精确的东西,你必须开始做英语语法分析,这是一个相当大的蠕虫(并假设正确使用语法,无论如何,这并不总是一个给定的)。
要确定一个字符串是否包含另一个字符串,可以使用php函数strpos()。
1 2 3 4 5 6 7 8 9 10 | <?php $haystack = 'how are you'; $needle = 'are'; if (strpos($haystack,$needle) !== false) { echo"$haystack contains $needle"; } ?> |
警告:
如果你寻找的针在干草堆的开始,它将返回位置0,如果你做一个
看看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?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."; } ?> |
使用
看看Samgoody和乐高冲锋队的评论。
如果您正在寻找一个PHP算法来根据多个词的接近度/相关性对搜索结果进行排名这里提供了一种只使用PHP生成搜索结果的简单快捷的方法:
其他布尔搜索方法的问题,如
基于向量空间模型和tf idf(词条频率-文档逆频率)的php方法:
这听起来很难,但却非常容易。
如果我们想在一个字符串中搜索多个单词,核心问题是如何为每个单词分配权重?
如果我们可以根据字符串整体的代表性对字符串中的术语进行加权,我们可以按与查询最匹配的结果排序。
这是向量空间模型的概念,与SQL全文搜索的工作方式相差不远:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 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
1 2 3 4 5 6 7 8 9 10 |
;< /代码>
结果
1 2 3 4 |
案例2
1 2 3 4 5 6 7 8 9 10 11 12 |
;< /代码>
结果
1 2 3 4 5 |
案例3
1 2 3 4 5 6 7 8 9 10 11 12 |
;< /代码>
结果
1 2 3 4 5 |
还有很多改进要做但是该模型提供了一种从自然查询中获得良好结果的方法,它没有布尔运算符,如
诺塔宾
可以选择在搜索单词之前消除冗余
从而减小索引大小,减少存储需求
更少的磁盘I/O
更快的索引和搜索速度。
1。规格化
- 将所有文本转换为小写
2。停止字消除
- 从文本中删除没有真正意义的单词(如"and"、"or"、"the"、"for"等)。
三。词典替换
用其他含义相同或相似的词替换。(例如:将"饥饿"和"饥饿"替换为"饥饿")。
可以执行进一步的算法措施(雪球)以进一步减少单词的本质意义。
用十六进制等价物替换颜色名
通过降低精度来减少数值是使文本正常化的其他方法。
资源
- 网址: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_模型
- http://en.wikipedia.org/wiki/tf%e2%80%93idf
- http://phpir.com/simple-search-the-vector-space-model/
使用
1 2 3 |
如果您想避免"虚假"和"真实"问题,可以使用SUBSTR U COUNT:
1 2 3 |
它比strpos慢一点,但避免了比较问题。
另一个选项是使用strstr()函数。类似:
注意:strstrstr()函数区分大小写。对于不区分大小写的搜索,请使用stristr()函数。
这里使用
基本上,如果您在查找某些语言(如德语、法语、葡萄牙语、西班牙语等)特定字符的单词时遇到困难(例如:?,埃??,O??),您可能希望在函数前面加上
1 2 3 |
如果不能保证所有数据都是100%的UTF-8格式,则可能需要使用
一篇很好的文章来理解为什么绝对是最低限度的,每个软件开发人员绝对,肯定必须了解Unicode和字符集(没有借口!)乔尔·斯波斯基。
1 2 3 |
下面的函数也可以工作,不依赖于任何其他函数;它只使用本机PHP字符串操作。就个人而言,我不推荐这样做,但您可以看到它是如何工作的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | <?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; } } |
测试:
1 2 3 4 5 6 7 | 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 |
在PHP中,验证字符串是否包含某个子字符串的最佳方法是使用如下简单的helper函数:
1 2 3 4 5 |
说明:
strpos 查找字符串中区分大小写的子字符串第一次出现的位置。stripos 查找字符串中不区分大小写的子字符串第一次出现的位置。myFunction($haystack, $needle) === FALSE ? FALSE : TRUE 确保myFunction 始终返回布尔值,并在子字符串的索引为0时修复意外行为。$caseSensitive ? A : B 根据$caseSensitive 的值,选择strpos 或stripos 进行工作。
输出:
1 2 3 4 5 6 7 8 9 10 11 12 | 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) |
您可以使用
1 2 3 4 5 6 7 8 | $haystack ="I know programming"; $needle ="know"; $flag = strstr($haystack, $needle); if ($flag){ echo"true"; } |
不使用内置函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
我在这方面遇到了一些困难,最后我选择创建自己的解决方案。不使用正则表达式引擎:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
您可能会注意到,前面的解决方案并不是用作另一个词前缀的单词的答案。为了使用您的示例:
1 2 3 | $a = 'How are you?'; $b ="a skirt that flares from the waist"; $c ="are"; |
对于上述样本,
使用strstr()和stristr()从字符串中查找单词出现的另一个选项如下:
1 2 3 4 5 6 7 |
速记版
1 |
为了找到一个"单词",而不是一系列字母的出现,这些字母实际上可能是另一个单词的一部分,下面将是一个很好的解决方案。
1 2 3 4 5 6 |
它可以通过三种不同的方式完成:
1 | $a = 'How are you?'; |
1 -串()
2 -()
1 2 3 |
3 -预匹配()
1 2 3 |
您应该使用不区分大小写的格式,因此,如果输入的值是
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?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样本
使用
1 |
要检查是否存在,请添加
1 |
也许你可以用这样的东西:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php findWord('Test all OK'); function findWord($text) { if (strstr($text, 'ok')) { echo 'Found a word'; } else { echo 'Did not find a word'; } } ?> |
如果只想检查一个字符串是否包含在另一个字符串中,则不要使用
1 2 3 |
如果要检查字符串是否包含多个特定单词,可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 | $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函数工作得很好,但是如果你想在段落中检查一个单词,那么你可以使用
例如,
1 2 3 4 5 6 7 | $result = stripos("I love PHP, I love PHP too!","php"); if ($result === false) { // Word does not exist } else { // Word exists } |
查找字符串中不区分大小写的子字符串的第一个匹配项的位置。
如果字符串中不存在该单词,则返回false,否则返回该单词的位置。
您需要使用相同/不相同的运算符,因为strpos可以返回0作为其索引值。如果您喜欢三元运算符,请考虑使用以下运算符(我承认似乎有点向后):
1 |
Check if string contains specific words?
这意味着字符串必须解析为单词(见下面的注释)。
这样做和指定分隔符的一种方法是使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?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 ."' "; } else { echo"string '" . $str ."' does not contain word '" . $word ."' " ; } } $a = 'How are you?'; test($a, 'are'); test($a, 'ar'); test($a, 'hare'); ?> |
一次赛跑
1 2 3 4 | $ 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正则表达式引擎的意义上,其中单词是仅由单词字符组成的子字符串,由非单词字符分隔。
A"word" character is any letter or digit or the underscore character,
that is, any character which can be part of a Perl" word". The
definition of letters and digits is controlled by PCRE's character
tables, and may vary if locale-specific matching is taking place (..)
可以使用以下函数检查字符串:
1 2 3 4 5 6 | function either_String_existor_not($str, $character) { if (strpos($str, $character) !== false) { return true; } return false; } |
特定字符串的另一个解决方案:
1 2 3 4 5 6 | $subject = 'How are you?'; $pattern = '/are/'; preg_match($pattern, $subject, $match); if ($match[0] == 'are') { echo true; } |
您还可以使用
用途:
1 2 3 4 5 6 7 8 | $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"; } |
我认为一个好主意是使用
1 2 3 4 5 6 7 | $haystack = 'How are you?'; $needle = 'are'; if (mb_strpos($haystack, $needle) !== false) { echo 'true'; } |
因为这个解决方案对所有Unicode字符都是区分大小写和安全的。
但你也可以这样做(Sauch还没有回应):
此解决方案对Unicode字符也区分大小写且安全。
此外,表达式中不使用否定,这会增加代码的可读性。
下面是其他使用函数的解决方案:
1 2 3 4 5 6 7 8 9 |
更简单的选择:
用途:
1 2 3 4 |
它执行多字节安全strpos()操作。
您还可以使用内置函数
strchr() —查找字符串的第一个匹配项(是strstr() 的别名)。strrchr() —查找字符串中最后出现的字符。