Using an array as needles in strpos

2019-01-01 13:14发布

问题:

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

回答1:

@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($haystack, $needle, $offset=0) {
    if(!is_array($needle)) $needle = array($needle);
    foreach($needle as $query) {
        if(strpos($haystack, $query, $offset) !== false) return true; // stop on first true result
    }
    return false;
}
$string = \'Whis string contains word \"cheese\" and \"tea\".\';
$array  = array(\'burger\', \'melon\', \'cheese\', \'milk\');
var_dump(strposa($string, $array)); // will return true, since \"cheese\" has been found


回答2:

str_replace is considerably faster.

$find_letters = array(\'a\', \'c\', \'d\');
$string = \'abcdefg\';
$match = (str_replace($find_letters, \'\', $string) != $string);


回答3:

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 


回答4:

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.



回答5:

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
}


回答6:

This expression searches for all letters:

count(array_filter( 
    array_map(\"strpos\", array_fill(0, count($letters), $str), $letters),
\"is_int\")) == count($letters)


回答7:

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!\';
}


回答8:

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.



回答9:

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.



回答10:

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.



回答11:

You can try this:

function in_array_strpos($word, $array){

foreach($array as $a){

    if (strpos($word,$a) !== false) {
        return true;
    }
}

return false;
}


回答12:

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));


回答13:

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;
}


回答14:

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;
}