You could use regular expressions as it's better for word matching compared to strpos
, as mentioned by other users. A strops
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