Related
This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
Consider:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Suppose I have the code above, what is the correct way to write the statement if ($a contains 'are')?
Now with PHP 8 you can do this using str_contains:
if (str_contains('How are you', 'are')) {
echo 'true';
}
RFC
Before PHP 8
You can use the strpos() function which is used to find the occurrence of one string inside another one:
$haystack = 'How are you?';
$needle = 'are';
if (strpos($haystack, $needle) !== false) {
echo 'true';
}
Note that the use of !== false is deliberate (neither != false nor === true will return the desired result); strpos() returns either the offset at which the needle string begins in the haystack string, or the boolean false if the needle isn't found. Since 0 is a valid offset and 0 is "falsey", we can't use simpler constructs like !strpos($a, 'are').
You could use regular expressions as it's better for word matching compared to strpos, as mentioned by other users. A strpos check for are will also return true for strings such as: fare, care, stare, etc. These unintended matches can simply be avoided in regular expression by using word boundaries.
A simple match for are could look something like this:
$a = 'How are you?';
if (preg_match('/\bare\b/', $a)) {
echo 'true';
}
On the performance side, strpos is about three times faster. When I did one million compares at once, it took preg_match 1.5 seconds to finish and for strpos it took 0.5 seconds.
Edit:
In order to search any part of the string, not just word by word, I would recommend using a regular expression like
$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
echo 'true';
}
The i at the end of regular expression changes regular expression to be case-insensitive, if you do not want that, you can leave it out.
Now, this can be quite problematic in some cases as the $search string isn't sanitized in any way, I mean, it might not pass the check in some cases as if $search is a user input they can add some string that might behave like some different regular expression...
Also, here's a great tool for testing and seeing explanations of various regular expressions Regex101
To combine both sets of functionality into a single multi-purpose function (including with selectable case sensitivity), you could use something like this:
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.
}
One more thing to take in mind, is that \b will not work in different languages other than english.
The explanation for this and the solution is taken from here:
\b represents the beginning or end of a word (Word Boundary). This
regex would match apple in an apple pie, but wouldn’t match apple in
pineapple, applecarts or bakeapples.
How about “café”? How can we extract the word “café” in regex?
Actually, \bcafé\b wouldn’t work. Why? Because “café” contains
non-ASCII character: é. \b can’t be simply used with Unicode such as
समुद्र, 감사, месяц and 😉 .
When you want to extract Unicode characters, you should directly
define characters which represent word boundaries.
The answer: (?<=[\s,.:;"']|^)UNICODE_WORD(?=[\s,.:;"']|$)
So in order to use the answer in PHP, you can use this function:
function contains($str, array $arr) {
// Works in Hebrew and any other unicode characters
// Thanks https://medium.com/#shiba1014/regex-word-boundaries-with-unicode-207794f6e7ed
// Thanks https://www.phpliveregex.com/
if (preg_match('/(?<=[\s,.:;"\']|^)' . $word . '(?=[\s,.:;"\']|$)/', $str)) return true;
}
And if you want to search for array of words, you can use this:
function arrayContainsWord($str, array $arr)
{
foreach ($arr as $word) {
// Works in Hebrew and any other unicode characters
// Thanks https://medium.com/#shiba1014/regex-word-boundaries-with-unicode-207794f6e7ed
// Thanks https://www.phpliveregex.com/
if (preg_match('/(?<=[\s,.:;"\']|^)' . $word . '(?=[\s,.:;"\']|$)/', $str)) return true;
}
return false;
}
As of PHP 8.0.0 you can now use str_contains
<?php
if (str_contains('abc', '')) {
echo "Checking the existence of the empty string will always"
return true;
}
Here is a little utility function that is useful in situations like this
// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
return strpos($haystack, $needle) !== false;
}
To determine whether a string contains another string you can use the PHP function 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";
}
?>
CAUTION:
If the needle you are searching for is at the beginning of the haystack it will return position 0, if you do a == compare that will not work, you will need to do a ===
A == sign is a comparison and tests whether the variable / expression / constant to the left has the same value as the variable / expression / constant to the right.
A === sign is a comparison to see whether two variables / expresions / constants are equal AND have the same type - i.e. both are strings or both are integers.
One of the advantages of using this approach is that every PHP version supports this function, unlike str_contains().
While most of these answers will tell you if a substring appears in your string, that's usually not what you want if you're looking for a particular word, and not a substring.
What's the difference? Substrings can appear within other words:
The "are" at the beginning of "area"
The "are" at the end of "hare"
The "are" in the middle of "fares"
One way to mitigate this would be to use a regular expression coupled with word boundaries (\b):
function containsWord($str, $word)
{
return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
This method doesn't have the same false positives noted above, but it does have some edge cases of its own. Word boundaries match on non-word characters (\W), which are going to be anything that isn't a-z, A-Z, 0-9, or _. That means digits and underscores are going to be counted as word characters and scenarios like this will fail:
The "are" in "What _are_ you thinking?"
The "are" in "lol u dunno wut those are4?"
If you want anything more accurate than this, you'll have to start doing English language syntax parsing, and that's a pretty big can of worms (and assumes proper use of syntax, anyway, which isn't always a given).
Look at strpos():
<?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.";
}
Using strstr() or stristr() if your search should be case insensitive would be another option.
Peer to SamGoody and Lego Stormtroopr comments.
If you are looking for a PHP algorithm to rank search results based on proximity/relevance of multiple words
here comes a quick and easy way of generating search results with PHP only:
Issues with the other boolean search methods such as strpos(), preg_match(), strstr() or stristr()
can't search for multiple words
results are unranked
PHP method based on Vector Space Model and tf-idf (term frequency–inverse document frequency):
It sounds difficult but is surprisingly easy.
If we want to search for multiple words in a string the core problem is how we assign a weight to each one of them?
If we could weight the terms in a string based on how representative they are of the string as a whole,
we could order our results by the ones that best match the query.
This is the idea of the vector space model, not far from how SQL full-text search works:
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;
}
CASE 1
$query = 'are';
$corpus = array(
1 => 'How are you?',
);
$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
print_r($match_results);
echo '</pre>';
RESULT
Array
(
[1] => 0.52832083357372
)
CASE 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>';
RESULTS
Array
(
[1] => 0.54248125036058
[3] => 0.21699250014423
)
CASE 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>';
RESULTS
Array
(
[3] => 0.6813781191217
[1] => 0.54248125036058
)
There are plenty of improvements to be made
but the model provides a way of getting good results from natural queries,
which don't have boolean operators such as strpos(), preg_match(), strstr() or stristr().
NOTA BENE
Optionally eliminating redundancy prior to search the words
thereby reducing index size and resulting in less storage requirement
less disk I/O
faster indexing and a consequently faster search.
1. Normalisation
Convert all text to lower case
2. Stopword elimination
Eliminate words from the text which carry no real meaning (like 'and', 'or', 'the', 'for', etc.)
3. Dictionary substitution
Replace words with others which have an identical or similar meaning.
(ex:replace instances of 'hungrily' and 'hungry' with 'hunger')
Further algorithmic measures (snowball) may be performed to further reduce words to their essential meaning.
The replacement of colour names with their hexadecimal equivalents
The reduction of numeric values by reducing precision are other ways of normalising the text.
RESOURCES
http://linuxgazette.net/164/sephton.html
http://snowball.tartarus.org/
MySQL Fulltext Search Score Explained
http://dev.mysql.com/doc/internals/en/full-text-search.html
http://en.wikipedia.org/wiki/Vector_space_model
http://en.wikipedia.org/wiki/Tf%E2%80%93idf
http://phpir.com/simple-search-the-vector-space-model/
Make use of case-insensitve matching using stripos():
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
If you want to avoid the "falsey" and "truthy" problem, you can use substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
It's a bit slower than strpos but it avoids the comparison problems.
if (preg_match('/(are)/', $a)) {
echo 'true';
}
Another option is to use the strstr() function. Something like:
if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}
Point to note: The strstr() function is case-sensitive. For a case-insensitive search, use the stristr() function.
I'm a bit impressed that none of the answers here that used strpos, strstr and similar functions mentioned Multibyte String Functions yet (2015-05-08).
Basically, if you're having trouble finding words with characters specific to some languages, such as German, French, Portuguese, Spanish, etc. (e.g.: ä, é, ô, ç, º, ñ), you may want to precede the functions with mb_. Therefore, the accepted answer would use mb_strpos or mb_stripos (for case-insensitive matching) instead:
if (mb_strpos($a,'are') !== false) {
echo 'true';
}
If you cannot guarantee that all your data is 100% in UTF-8, you may want to use the mb_ functions.
A good article to understand why is The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) by Joel Spolsky.
In PHP, the best way to verify if a string contains a certain substring, is to use a simple helper function like this:
function contains($haystack, $needle, $caseSensitive = false) {
return $caseSensitive ?
(strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
(stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}
Explanation:
strpos finds the position of the first occurrence of a case-sensitive substring in a string.
stripos finds the position of the first occurrence of a case-insensitive substring in a string.
myFunction($haystack, $needle) === FALSE ? FALSE : TRUE ensures that myFunction always returns a boolean and fixes unexpected behavior when the index of the substring is 0.
$caseSensitive ? A : B selects either strpos or stripos to do the work, depending on the value of $caseSensitive.
Output:
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)
You can use the strstr function:
$haystack = "I know programming";
$needle = "know";
$flag = strstr($haystack, $needle);
if ($flag){
echo "true";
}
Without using an inbuilt function:
$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 ";
}
The function below also works and does not depend on any other function; it uses only native PHP string manipulation. Personally, I do not recommend this, but you can see how it works:
<?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;
}
}
Test:
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
Lot of answers that use substr_count checks if the result is >0. But since the if statement considers zero the same as false, you can avoid that check and write directly:
if (substr_count($a, 'are')) {
To check if not present, add the ! operator:
if (!substr_count($a, 'are')) {
I had some trouble with this, and finally I chose to create my own solution. Without using regular expression engine:
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;
}
You may notice that the previous solutions are not an answer for the word being used as a prefix for another. In order to use your example:
$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";
With the samples above, both $a and $b contains $c, but you may want your function to tell you that only $a contains $c.
Another option to finding the occurrence of a word from a string using strstr() and stristr() is like the following:
<?php
$a = 'How are you?';
if (strstr($a,'are')) // Case sensitive
echo 'true';
if (stristr($a,'are')) // Case insensitive
echo 'true';
?>
It can be done in three different ways:
$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
}
The short-hand version
$result = false!==strpos($a, 'are');
Do not use preg_match() if you only want to check if one string is contained in another string. Use strpos() or strstr() instead as they will be faster. (http://in2.php.net/preg_match)
if (strpos($text, 'string_name') !== false){
echo 'get the string';
}
In order to find a 'word', rather than the occurrence of a series of letters that could in fact be a part of another word, the following would be a good solution.
$string = 'How are you?';
$array = explode(" ", $string);
if (in_array('are', $array) ) {
echo 'Found the word';
}
You should use case Insensitive format,so if the entered value is in small or caps it wont matter.
<?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";
}
?>
Here stripos finds needle in heystack without considering case (small/caps).
PHPCode Sample with output
Maybe you could use something like this:
<?php
findWord('Test all OK');
function findWord($text) {
if (strstr($text, 'ok')) {
echo 'Found a word';
}
else
{
echo 'Did not find a word';
}
}
?>
If you want to check if the string contains several specifics words, you can do:
$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";
}
This is useful to avoid spam when sending emails for example.
The strpos function works fine, but if you want to do case-insensitive checking for a word in a paragraph then you can make use of the stripos function of PHP.
For example,
$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
// Word does not exist
}
else {
// Word exists
}
Find the position of the first occurrence of a case-insensitive substring in a string.
If the word doesn't exist in the string then it will return false else it will return the position of the word.
A string can be checked with the below function:
function either_String_existor_not($str, $character) {
return strpos($str, $character) !== false;
}
You need to use identical/not identical operators because strpos can return 0 as it's index value. If you like ternary operators, consider using the following (seems a little backwards I'll admit):
echo FALSE === strpos($a,'are') ? 'false': 'true';
Check if string contains specific words?
This means the string has to be resolved into words (see note below).
One way to do this and to specify the separators is using 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');
?>
A run gives
$ 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'
Note: Here we do not mean word for every sequence of symbols.
A practical definition of word is in the sense the PCRE regular expression engine, where words are substrings consisting of word characters only, being separated by non-word characters.
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 (..)
Does anyone know how to write regex pattern, that does this:
let's say I have letters in array like
$letters = array('a','b','a');
and also we have a word Alabama and I want preg_match to return true, since it contains letter A two times and B. But it should return false on word Ab, because there aren't two A in that word.
Any ideas ?
EDIT: the only pattern I tried was [a,b,a] but it returns true on every word that does contain one of these letters and also doesn't check it for multiple letter occurences
I think you don't have to overcomplicate the process. You can traverse the letters and check if the exists in the word, if all the letter are there, return true. Something like this:
$letters = array('a','b','a');
$word = "Alabama";
function inWord($l,$w){
//For each letter
foreach($l as $letter){
//check if the letter is in the word
if(($p = stripos($w,$letter)) === FALSE)
//if false, return false
return FALSE;
else
//if the letter is there, remove it and move to the next one
$w = substr_replace($w,'',$p,1);
}
//If it found all the letters, return true
return TRUE;
}
And use it like this: inWord($letters,$word);
Please note this is case insensitive, if you need it case sensitive replace stripos by strpos
Must you need to use regular expressions? Even if the problem can be solved through them, the code will be very complicated.
"Manual" solution will be clearer and takes linear time:
function stringContainsAllCharacters(string $str, array $chars): bool
{
$actualCharCounts = array_count_values(str_split($str));
$requiredCharCounts = array_count_values($chars);
foreach ($requiredCharCounts as $char => $count) {
if (!array_key_exists($char, $actualCharCounts) || $actualCharCounts[$char] < $count) {
return false;
}
}
return true;
}
I have a website connected to a web service and I need to recognize the characters received in my codes.
For instance, I receive a message like this :
$str = "Hello Europe";
or :
$str = "4 times !";
or :
$str = "452231";
or :
$str= "*Majid SH";
or ...
I want my code to understand the character which my message started by, and do the a function correspond to a special character.
For example, if it was started by a string, do function num1, or if it was started by '.' [dot], do function num2.
Thank you for helping me.
You can use substr() as follows:
Code:
$char1 = substr($str, 0, 1); //getting first character
if(is_numeric($char1){
//execute num1()
num1();
}
elseif ($char1 == '.') {
//execute num1()
num2();
}
I would use strpos()
<?php
$StringFromService;
$str = "Hello Europe";
$Search = strpos($StringFromService;, $str);
if ($Search === true) {
// run function
}
?>
You should use the switch If you want to find out if the character is a specific thing like a comma or period. Also understand that Strings can simply be thought of as Char arrays so you can simply call $str[0] to get the first char (See here.)
switch ($str[0]) {
case ",":
num1();
break;
case ".":
num2();
break;
}
You can keep making different cases to handle different situations. Just make sure you include a break between each case.
If you want to check if something is a string I believe there is an is_string but for that you may need to use substr as many other people have recommended because $str[0] I believe returns a char and not a string so it won't verify. The switch statement simply checks if the parameter is the same as the case using loose comparison. If you want more advanced checking, you'll probably need to use your own if statement to check or even regex. Hope this helps.
$str = 'value'; // value
$firstChar = substr($str, 0, 1);
if (is_numeric($firstChar)) {
// do something numeric'
} else if ($firstChar === '.') {
// do something dot'
} else {
// do something string'
}
So I get how to replace certain words with other ones. What I'm trying to figure out is how to take a word and replace it with a phrase and eliminate all other input.
For example:
bad word is 'dog'
user inputs -> 'You smell like a dog.'
instead of it replacing 'dog' with 'rainbow' or something, I want it to echo something like: 'You are a potty mouth'.
Here's what I have for code:
<?php
$find = array('dog', 'cat', 'bird');
$replace = 'You are a potty mouth.';
if (isset ($_POST['user_input'])&&!empty($_POST['user_input'])) {
$user_input = $_POST['user_input'];
$user_input_new = str_ireplace($find, $replace, $user_input);
echo $user_input_new;
}
?>
With this code it echos: 'You smell like a You are a pottymouth.'
I'm sure this is a repost and I apologize. Everything I've been able to find is documentation on how to replace only parts of strings, not entire ones.
Well, in this case you can just check whether there is a "bad word" in the user input string, and if it returns true, echo "You are a potty mouth."
You would want to use strpos()
e.g.
if( strpos($_POST['user_input'],'dog')!==FALSE ) {
echo('You are a potty mouth');
}
If you have an array of "bad words" you'll want to loop through them to check any occur within user input.
I've been looking at the same issue recently, here's a script I was working on to filter certain words. Still a work in progress but it has the ability to output the user message or a custom message. Hope it helps or points you in the right direction.
define("MIN_SAFE_WORD_LIMIT", 3);
$safe = true;
$whiteList = array();
$blackList = array();
$text = 'Test words fRom a piece of text.';
$blCount = count($blackList);
for($i=0; $i<$blCount; $i++) {
if((strlen($blackList[$i]) >= MIN_SAFE_WORD_LIMIT) && strstr(strtolower($text), strtolower($blackList[$i])) && !strstr(strtolower($text), strtolower($whiteList[$i]))) {
$safe = false;
}
}
if(!$safe) {
// Unsafe, flag for action
echo 'Unsafe';
} else {
echo $text;
}
You don't want to replace the bad words, but the whole string, so you should just match and if matched set the whole string to your replacement string.
Also, as pointed out in the comments the words can be part of another, valid, word so if you want to take that into account, you should match only whole words.
This simple example uses word boundaries in a regular expression to match your words (in the example this would be in a loop, looping over your bad words array):
foreach ($find as $your_word)
{
$search = '/\b' . preg_quote($your_word) . '\b/i';
if (preg_match($search, $_POST['user_input']) === 1)
{
// a match is found, echo or set it to a variable, whatever you need
echo $replace;
// break out of the loop
break;
}
}
Heres an alternative solution, match words and replace with * len of str. this wont match words like Scunthorpe as it uses word boundaries, Also you you can add a 3rd param to reveal the first letters of the word so you know what word was said without seeing it.
<?php
$badwords = array('*c word', '*f word','badword','stackoverflow');
function swear_filter($str,$badwords,$reveal=null) {
//Alternatively load from file
//$words = join("|", array_filter(array_map('preg_quote',array_map('trim', file('badwords.txt')))));
$words = join("|", array_filter(array_map('preg_quote',array_map('trim', $badwords))));
if($reveal !=null && is_numeric($reveal)){
return preg_replace("/\b($words)\b/uie", '"".substr("$1",0,'.$reveal.').str_repeat("*",strlen("$1")-'.$reveal.').""', $str);
}else{
return preg_replace("/\b($words)\b/uie", '"".str_repeat("*",strlen("$1")).""', $str);
}
}
$str="There was a naughty Peacock from Scunthorpe and it said a badword, on stackoverflow";
//There was a naughty Peacock from Scunthorpe and it said a b******, on s************
echo swear_filter($str,$badwords,1);
//There was a naughty Peacock from Scunthorpe and it said a *******, on *************
echo swear_filter($str,$badwords);
?>
This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
Consider:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Suppose I have the code above, what is the correct way to write the statement if ($a contains 'are')?
Now with PHP 8 you can do this using str_contains:
if (str_contains('How are you', 'are')) {
echo 'true';
}
RFC
Before PHP 8
You can use the strpos() function which is used to find the occurrence of one string inside another one:
$haystack = 'How are you?';
$needle = 'are';
if (strpos($haystack, $needle) !== false) {
echo 'true';
}
Note that the use of !== false is deliberate (neither != false nor === true will return the desired result); strpos() returns either the offset at which the needle string begins in the haystack string, or the boolean false if the needle isn't found. Since 0 is a valid offset and 0 is "falsey", we can't use simpler constructs like !strpos($a, 'are').
You could use regular expressions as it's better for word matching compared to strpos, as mentioned by other users. A strpos check for are will also return true for strings such as: fare, care, stare, etc. These unintended matches can simply be avoided in regular expression by using word boundaries.
A simple match for are could look something like this:
$a = 'How are you?';
if (preg_match('/\bare\b/', $a)) {
echo 'true';
}
On the performance side, strpos is about three times faster. When I did one million compares at once, it took preg_match 1.5 seconds to finish and for strpos it took 0.5 seconds.
Edit:
In order to search any part of the string, not just word by word, I would recommend using a regular expression like
$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
echo 'true';
}
The i at the end of regular expression changes regular expression to be case-insensitive, if you do not want that, you can leave it out.
Now, this can be quite problematic in some cases as the $search string isn't sanitized in any way, I mean, it might not pass the check in some cases as if $search is a user input they can add some string that might behave like some different regular expression...
Also, here's a great tool for testing and seeing explanations of various regular expressions Regex101
To combine both sets of functionality into a single multi-purpose function (including with selectable case sensitivity), you could use something like this:
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.
}
One more thing to take in mind, is that \b will not work in different languages other than english.
The explanation for this and the solution is taken from here:
\b represents the beginning or end of a word (Word Boundary). This
regex would match apple in an apple pie, but wouldn’t match apple in
pineapple, applecarts or bakeapples.
How about “café”? How can we extract the word “café” in regex?
Actually, \bcafé\b wouldn’t work. Why? Because “café” contains
non-ASCII character: é. \b can’t be simply used with Unicode such as
समुद्र, 감사, месяц and 😉 .
When you want to extract Unicode characters, you should directly
define characters which represent word boundaries.
The answer: (?<=[\s,.:;"']|^)UNICODE_WORD(?=[\s,.:;"']|$)
So in order to use the answer in PHP, you can use this function:
function contains($str, array $arr) {
// Works in Hebrew and any other unicode characters
// Thanks https://medium.com/#shiba1014/regex-word-boundaries-with-unicode-207794f6e7ed
// Thanks https://www.phpliveregex.com/
if (preg_match('/(?<=[\s,.:;"\']|^)' . $word . '(?=[\s,.:;"\']|$)/', $str)) return true;
}
And if you want to search for array of words, you can use this:
function arrayContainsWord($str, array $arr)
{
foreach ($arr as $word) {
// Works in Hebrew and any other unicode characters
// Thanks https://medium.com/#shiba1014/regex-word-boundaries-with-unicode-207794f6e7ed
// Thanks https://www.phpliveregex.com/
if (preg_match('/(?<=[\s,.:;"\']|^)' . $word . '(?=[\s,.:;"\']|$)/', $str)) return true;
}
return false;
}
As of PHP 8.0.0 you can now use str_contains
<?php
if (str_contains('abc', '')) {
echo "Checking the existence of the empty string will always"
return true;
}
Here is a little utility function that is useful in situations like this
// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
return strpos($haystack, $needle) !== false;
}
To determine whether a string contains another string you can use the PHP function 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";
}
?>
CAUTION:
If the needle you are searching for is at the beginning of the haystack it will return position 0, if you do a == compare that will not work, you will need to do a ===
A == sign is a comparison and tests whether the variable / expression / constant to the left has the same value as the variable / expression / constant to the right.
A === sign is a comparison to see whether two variables / expresions / constants are equal AND have the same type - i.e. both are strings or both are integers.
One of the advantages of using this approach is that every PHP version supports this function, unlike str_contains().
While most of these answers will tell you if a substring appears in your string, that's usually not what you want if you're looking for a particular word, and not a substring.
What's the difference? Substrings can appear within other words:
The "are" at the beginning of "area"
The "are" at the end of "hare"
The "are" in the middle of "fares"
One way to mitigate this would be to use a regular expression coupled with word boundaries (\b):
function containsWord($str, $word)
{
return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
This method doesn't have the same false positives noted above, but it does have some edge cases of its own. Word boundaries match on non-word characters (\W), which are going to be anything that isn't a-z, A-Z, 0-9, or _. That means digits and underscores are going to be counted as word characters and scenarios like this will fail:
The "are" in "What _are_ you thinking?"
The "are" in "lol u dunno wut those are4?"
If you want anything more accurate than this, you'll have to start doing English language syntax parsing, and that's a pretty big can of worms (and assumes proper use of syntax, anyway, which isn't always a given).
Look at strpos():
<?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.";
}
Using strstr() or stristr() if your search should be case insensitive would be another option.
Peer to SamGoody and Lego Stormtroopr comments.
If you are looking for a PHP algorithm to rank search results based on proximity/relevance of multiple words
here comes a quick and easy way of generating search results with PHP only:
Issues with the other boolean search methods such as strpos(), preg_match(), strstr() or stristr()
can't search for multiple words
results are unranked
PHP method based on Vector Space Model and tf-idf (term frequency–inverse document frequency):
It sounds difficult but is surprisingly easy.
If we want to search for multiple words in a string the core problem is how we assign a weight to each one of them?
If we could weight the terms in a string based on how representative they are of the string as a whole,
we could order our results by the ones that best match the query.
This is the idea of the vector space model, not far from how SQL full-text search works:
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;
}
CASE 1
$query = 'are';
$corpus = array(
1 => 'How are you?',
);
$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
print_r($match_results);
echo '</pre>';
RESULT
Array
(
[1] => 0.52832083357372
)
CASE 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>';
RESULTS
Array
(
[1] => 0.54248125036058
[3] => 0.21699250014423
)
CASE 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>';
RESULTS
Array
(
[3] => 0.6813781191217
[1] => 0.54248125036058
)
There are plenty of improvements to be made
but the model provides a way of getting good results from natural queries,
which don't have boolean operators such as strpos(), preg_match(), strstr() or stristr().
NOTA BENE
Optionally eliminating redundancy prior to search the words
thereby reducing index size and resulting in less storage requirement
less disk I/O
faster indexing and a consequently faster search.
1. Normalisation
Convert all text to lower case
2. Stopword elimination
Eliminate words from the text which carry no real meaning (like 'and', 'or', 'the', 'for', etc.)
3. Dictionary substitution
Replace words with others which have an identical or similar meaning.
(ex:replace instances of 'hungrily' and 'hungry' with 'hunger')
Further algorithmic measures (snowball) may be performed to further reduce words to their essential meaning.
The replacement of colour names with their hexadecimal equivalents
The reduction of numeric values by reducing precision are other ways of normalising the text.
RESOURCES
http://linuxgazette.net/164/sephton.html
http://snowball.tartarus.org/
MySQL Fulltext Search Score Explained
http://dev.mysql.com/doc/internals/en/full-text-search.html
http://en.wikipedia.org/wiki/Vector_space_model
http://en.wikipedia.org/wiki/Tf%E2%80%93idf
http://phpir.com/simple-search-the-vector-space-model/
Make use of case-insensitve matching using stripos():
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
If you want to avoid the "falsey" and "truthy" problem, you can use substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
It's a bit slower than strpos but it avoids the comparison problems.
if (preg_match('/(are)/', $a)) {
echo 'true';
}
Another option is to use the strstr() function. Something like:
if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}
Point to note: The strstr() function is case-sensitive. For a case-insensitive search, use the stristr() function.
I'm a bit impressed that none of the answers here that used strpos, strstr and similar functions mentioned Multibyte String Functions yet (2015-05-08).
Basically, if you're having trouble finding words with characters specific to some languages, such as German, French, Portuguese, Spanish, etc. (e.g.: ä, é, ô, ç, º, ñ), you may want to precede the functions with mb_. Therefore, the accepted answer would use mb_strpos or mb_stripos (for case-insensitive matching) instead:
if (mb_strpos($a,'are') !== false) {
echo 'true';
}
If you cannot guarantee that all your data is 100% in UTF-8, you may want to use the mb_ functions.
A good article to understand why is The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) by Joel Spolsky.
In PHP, the best way to verify if a string contains a certain substring, is to use a simple helper function like this:
function contains($haystack, $needle, $caseSensitive = false) {
return $caseSensitive ?
(strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
(stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}
Explanation:
strpos finds the position of the first occurrence of a case-sensitive substring in a string.
stripos finds the position of the first occurrence of a case-insensitive substring in a string.
myFunction($haystack, $needle) === FALSE ? FALSE : TRUE ensures that myFunction always returns a boolean and fixes unexpected behavior when the index of the substring is 0.
$caseSensitive ? A : B selects either strpos or stripos to do the work, depending on the value of $caseSensitive.
Output:
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)
You can use the strstr function:
$haystack = "I know programming";
$needle = "know";
$flag = strstr($haystack, $needle);
if ($flag){
echo "true";
}
Without using an inbuilt function:
$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 ";
}
The function below also works and does not depend on any other function; it uses only native PHP string manipulation. Personally, I do not recommend this, but you can see how it works:
<?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;
}
}
Test:
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
Lot of answers that use substr_count checks if the result is >0. But since the if statement considers zero the same as false, you can avoid that check and write directly:
if (substr_count($a, 'are')) {
To check if not present, add the ! operator:
if (!substr_count($a, 'are')) {
I had some trouble with this, and finally I chose to create my own solution. Without using regular expression engine:
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;
}
You may notice that the previous solutions are not an answer for the word being used as a prefix for another. In order to use your example:
$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";
With the samples above, both $a and $b contains $c, but you may want your function to tell you that only $a contains $c.
Another option to finding the occurrence of a word from a string using strstr() and stristr() is like the following:
<?php
$a = 'How are you?';
if (strstr($a,'are')) // Case sensitive
echo 'true';
if (stristr($a,'are')) // Case insensitive
echo 'true';
?>
It can be done in three different ways:
$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
}
The short-hand version
$result = false!==strpos($a, 'are');
Do not use preg_match() if you only want to check if one string is contained in another string. Use strpos() or strstr() instead as they will be faster. (http://in2.php.net/preg_match)
if (strpos($text, 'string_name') !== false){
echo 'get the string';
}
In order to find a 'word', rather than the occurrence of a series of letters that could in fact be a part of another word, the following would be a good solution.
$string = 'How are you?';
$array = explode(" ", $string);
if (in_array('are', $array) ) {
echo 'Found the word';
}
You should use case Insensitive format,so if the entered value is in small or caps it wont matter.
<?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";
}
?>
Here stripos finds needle in heystack without considering case (small/caps).
PHPCode Sample with output
Maybe you could use something like this:
<?php
findWord('Test all OK');
function findWord($text) {
if (strstr($text, 'ok')) {
echo 'Found a word';
}
else
{
echo 'Did not find a word';
}
}
?>
If you want to check if the string contains several specifics words, you can do:
$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";
}
This is useful to avoid spam when sending emails for example.
The strpos function works fine, but if you want to do case-insensitive checking for a word in a paragraph then you can make use of the stripos function of PHP.
For example,
$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
// Word does not exist
}
else {
// Word exists
}
Find the position of the first occurrence of a case-insensitive substring in a string.
If the word doesn't exist in the string then it will return false else it will return the position of the word.
A string can be checked with the below function:
function either_String_existor_not($str, $character) {
return strpos($str, $character) !== false;
}
You need to use identical/not identical operators because strpos can return 0 as it's index value. If you like ternary operators, consider using the following (seems a little backwards I'll admit):
echo FALSE === strpos($a,'are') ? 'false': 'true';
Check if string contains specific words?
This means the string has to be resolved into words (see note below).
One way to do this and to specify the separators is using 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');
?>
A run gives
$ 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'
Note: Here we do not mean word for every sequence of symbols.
A practical definition of word is in the sense the PCRE regular expression engine, where words are substrings consisting of word characters only, being separated by non-word characters.
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 (..)