Using an array as needles in strpos
PhpArraysStrposPhp Problem Overview
How do you use the strpos
for an array of needles when searching a string? For example:
$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';
if(strpos($string, $find_letters) !== false)
{
echo 'All the letters are found in the string!';
}
Because when using this, it wouldn't work, it would be good if there was something like this
Php Solutions
Solution 1 - Php
@Dave an updated snippet from http://www.php.net/manual/en/function.strpos.php#107351
function strposa($haystack, $needles=array(), $offset=0) {
$chr = array();
foreach($needles as $needle) {
$res = strpos($haystack, $needle, $offset);
if ($res !== false) $chr[$needle] = $res;
}
if(empty($chr)) return false;
return min($chr);
}
How to use:
$string = 'Whis string contains word "cheese" and "tea".';
$array = array('burger', 'melon', 'cheese', 'milk');
if (strposa($string, $array, 1)) {
echo 'true';
} else {
echo 'false';
}
will return true
, because of array
"cheese"
.
Update: Improved code with stop when the first of the needles is found:
function strposa(string $haystack, array $needles, int $offset = 0): bool
{
foreach($needles as $needle) {
if(strpos($haystack, $needle, $offset) !== false) {
return true; // stop on first true result
}
}
return false;
}
$string = 'This string contains word "cheese" and "tea".';
$array = ['burger', 'melon', 'cheese', 'milk'];
var_dump(strposa($string, $array)); // will return true, since "cheese" has been found
Solution 2 - Php
str_replace is considerably faster.
$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';
$match = (str_replace($find_letters, '', $string) != $string);
Solution 3 - Php
The below code not only shows how to do it, but also puts it in an easy to use function moving forward. It was written by "jesda". (I found it online)
PHP Code:
<?php
/* strpos that takes an array of values to match against a string
* note the stupid argument order (to match strpos)
*/
function strpos_arr($haystack, $needle) {
if(!is_array($needle)) $needle = array($needle);
foreach($needle as $what) {
if(($pos = strpos($haystack, $what))!==false) return $pos;
}
return false;
}
?>
Usage:
$needle = array('something','nothing');
$haystack = "This is something";
echo strpos_arr($haystack, $needle); // Will echo True
$haystack = "This isn't anything";
echo strpos_arr($haystack, $needle); // Will echo False
Solution 4 - Php
The question, is the provided example just an "example" or exact what you looking for? There are many mixed answers here, and I dont understand the complexibility of the accepted one.
To find out if ANY content of the array of needles exists in the string, and quickly return true or false:
$string = 'abcdefg';
if(str_replace(array('a', 'c', 'd'), '', $string) != $string){
echo 'at least one of the needles where found';
};
If, so, please give @Leon credit for that.
To find out if ALL values of the array of needles exists in the string, as in this case, all three 'a', 'b'
and 'c'
MUST be present, like you mention as your "for example"
> echo 'All the letters are found in the string!';
Many answers here is out of that context, but I doubt that the intension of the question as you marked as resolved. E.g. The accepted answer is a needle of
$array = array('burger', 'melon', 'cheese', 'milk');
What if all those words MUST be found in the string?
Then you try out some "not accepted answers"
on this page.
Solution 5 - Php
You can iterate through the array and set a "flag" value if strpos
returns false
.
$flag = false;
foreach ($find_letters as $letter)
{
if (strpos($string, $letter) === false)
{
$flag = true;
}
}
Then check the value of $flag
.
Solution 6 - Php
If you just want to check if certain characters are actually in the string or not, use strtok:
$string = 'abcdefg';
if (strtok($string, 'acd') === $string) {
// not found
} else {
// found
}
Solution 7 - Php
This expression searches for all letters:
count(array_filter(
array_map("strpos", array_fill(0, count($letters), $str), $letters),
"is_int")) == count($letters)
Solution 8 - Php
You can try this:
function in_array_strpos($word, $array){
foreach($array as $a){
if (strpos($word,$a) !== false) {
return true;
}
}
return false;
}
Solution 9 - Php
You can also try using strpbrk() for the negation (none of the letters have been found):
$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';
if(strpbrk($string, implode($find_letters)) === false)
{
echo 'None of these letters are found in the string!';
}
Solution 10 - Php
This is my approach. Iterate over characters in the string until a match is found. On a larger array of needles this will outperform the accepted answer because it doesn't need to check every needle to determine that a match has been found.
function strpos_array($haystack, $needles = [], $offset = 0) {
for ($i = $offset, $len = strlen($haystack); $i < $len; $i++){
if (in_array($haystack[$i],$needles)) {
return $i;
}
}
return false;
}
I benchmarked this against the accepted answer and with an array of more than 7 $needles
this was dramatically faster.
Solution 11 - Php
With the following code:
$flag = true;
foreach($find_letters as $letter)
if(false===strpos($string, $letter)) {
$flag = false;
break;
}
Then check the value of $flag
. If it is true
, all letters have been found. If not, it's false
.
Solution 12 - Php
I'm writing a new answer which hopefully helps anyone looking for similar to what I am.
This works in the case of "I have multiple needles and I'm trying to use them to find a singled-out string". and this is the question I came across to find that.
$i = 0;
$found = array();
while ($i < count($needle)) {
$x = 0;
while ($x < count($haystack)) {
if (strpos($haystack[$x], $needle[$i]) !== false) {
array_push($found, $haystack[$x]);
}
$x++;
}
$i++;
}
$found = array_count_values($found);
The array $found
will contain a list of all the matching needles, the item of the array with the highest count value will be the string(s) you're looking for, you can get this with:
print_r(array_search(max($found), $found));
Solution 13 - Php
Reply to @binyamin and @Timo.. (not enough points to add a comment..) but the result doesn't contain the position..
The code below will return the actual position of the first element which is what strpos is intended to do. This is useful if you're expecting to find exactly 1 match.. If you're expecting to find multiple matches, then position of first found may be meaningless.
function strposa($haystack, $needle, $offset=0) {
if(!is_array($needle)) $needle = array($needle);
foreach($needle as $query) {
$res=strpos($haystack, $query, $offset);
if($res !== false) return $res; // stop on first true result
}
return false;
}
Solution 14 - Php
Just an upgrade from above answers
function strsearch($findme, $source){
if(is_array($findme)){
if(str_replace($findme, '', $source) != $source){
return true;
}
}else{
if(strpos($source,$findme)){
return true;
}
}
return false;
}
Solution 15 - Php
<?php
$Words = array("hello","there","world");
$c = 0;
$message = 'Hi hello';
foreach ($Words as $word):
$trial = stripos($message,$word);
if($trial != true){
$c++;
echo 'Word '.$c.' didnt match <br> <br>';
}else{
$c++;
echo 'Word '.$c.' matched <br> <br>';
}
endforeach;
?>
I used this kind of code to check for hello, It also Has a numbering feature. You can use this if you want to do content moderation practices in websites that need the user to type
Solution 16 - Php
If i just want to find out if any of the needles exist in the haystack, i use
reusable function
function strposar($arrayOfNeedles, $haystack){
if (count(array_filter($arrayOfNeedles, function($needle) use($haystack){
return strpos($haystack, $needle) !== false;
})) > 0){
return true;
} else {
return false;
}
}
strposar($arrayOfNeedles, $haystack); //returns true/false
or lambda function
if (count(array_filter($arrayOfNeedles, function($needle) use($haystack){
return strpos($haystack, $needle) !== false;
})) > 0){
//found so do this
} else {
//not found do this instead
}