strposで配列を針として使用する


89

strpos文字列を検索するときに、針の配列にをどのように使用しますか?例えば:

$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';

if(strpos($string, $find_letters) !== false)
{
    echo 'All the letters are found in the string!';
}

これを使うと動かないので、こんなものがあったらいいのに

回答:


134

@Dave 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);
}

使い方:

$string = 'Whis string contains word "cheese" and "tea".';
$array  = array('burger', 'melon', 'cheese', 'milk');

if (strposa($string, $array, 1)) {
    echo 'true';
} else {
    echo 'false';
}

trueために戻りarray "cheese"ます。

更新:最初の針が見つかったときに停止するコードの改善:

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

1
@Arnaud、あなたが提案する実装​​は何ですか?
Binyamin

5
よくわかりませんが、$ offsetから文字列を進めて、最初の針が見つかったときに停止することができます。「a」でいっぱいの大きなテキストについて考えてみてください。$ needles = [a、b]を取ります。関数strposaはすべてのテキストを実行しますが、必須ではありません。私は理解できますか?
Arnaud

機能の提案をありがとう@Arnaud!私はあなたの提案の重要性に完全に同意し、改善されたコード例で私の答えを更新しました。
Binyamin

新しい関数$ needles = [b、a]にはまだ問題があり、さらに関数は最初の発生の位置を返さないため、これは私が言いたかったこととは正確には異なります。もう少し説明しましょう。文字列が "ABCDEF"で、針がCとFであると仮定します。文字列を実行すると、A、B ... C!Cを検出したため、ここで停止し、最初に出現した針の位置(2)を返すことができます。これは、単一文字の文字列以上で機能する可能性がありますが、正確な実装については考えていません。
Arnaud

1
を変更することforeach($needle as $k => $query) { if(strpos($haystack, $query, $offset) !== false) return $k; }でコードを改善し、さらに処理するために一致するアイテムのキーを返します。
James Cameron

51

str_replaceはかなり高速です。

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

構文エラー:1行#3で閉じ括弧が多すぎます(> 6文字の編集要件のため、上のコードでは直接修正できませんでした;))
richey

1
おっと、それは袖口から外れていました。今修正されました。頑張ってください!
レオン

6
最大のソリューションの1つです。
アンディ

18

以下のコードは、その方法を示すだけでなく、使いやすい関数に組み込んでいます。「jesda」によって書かれました。(私はそれをオンラインで見つけました)

PHPコード:

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

使用法:

$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 

これは最初に見つけた位置のみを返すと思います。干し草の山のすべての針の位置を返すためにそれを微調整する方法についての提案はありますか?
Chaya Cooper

7

配列を反復処理し、strposが返されfalseた場合は「フラグ」値を設定できます。

$flag = false;
foreach ($find_letters as $letter)
{
    if (strpos($string, $letter) === false)
    {
        $flag = true;
    }
}

次に、の値を確認します$flag


6
そうじゃないの!== flase
Joe Huang

!== falseである必要があります。フラグをtrueに設定した直後に中断しない限り。そして、フラグが針が干し草の山にないという警告としてフラグを解釈する必要があります。つまり、達成しようとしているのは、すべての針が干し草の山にあることを確認することです。それは問題ではありません。そう..ええ。!== false
Kevin Gagnon 2016年

5

特定の文字が実際に文字列に含まれているかどうかを確認するだけの場合は、strtokを使用します。

$string = 'abcdefg';
if (strtok($string, 'acd') === $string) {
    // not found
} else {
    // found
}

信じられない答え-複数のstrpos()よりもはるかに高速に実行できます。たとえば、if(strpos($ string、 "a")!== false && strpos($ string、 "c")!== false && strpos($ string、 " d ")!== false)
唯一無二のChemistryBlob

5

質問、提供された例は単なる「例」ですか、それとも正確にあなたが探しているものですか?ここには多くの混合した答えがあり、私は受け入れられたものの複雑さを理解していません。

かどうかを確認するために、いかなるコンテンツの針の配列のは、文字列内に存在し、かつ迅速 trueまたはfalseを返します。

$string = 'abcdefg';

if(str_replace(array('a', 'c', 'd'), '', $string) != $string){
    echo 'at least one of the needles where found';
};

もしそうなら、そのために@Leonクレジットを与えてください。

かどうかを確認するために、すべての値の針の配列の存在が、この場合のように、文字列では、3つすべてを'a', 'b'して'c'、あなたが言及するように、存在していなければならないあなたの「例えば」として、

echo 'すべての文字が文字列に含まれています!';

ここでの多くの答えはその文脈から外れていますが、あなたが解決したとマークした質問の意図は疑問です。例えば受け入れられた答えはの針です

$array  = array('burger', 'melon', 'cheese', 'milk');

これらの単語がすべて文字列内になければならない場合はどうなりますか?

次に"not accepted answers"、このページでいくつか試します。


配列にサブストリングが含まれているのを探していたので、これは完璧に機能しました。「%$ string%」のようなsqlコマンドを書くことから救われました
Maurice Elagu

4

次の式は、すべての文字を検索します。

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

3

あなたはこれを試すことができます:

function in_array_strpos($word, $array){

foreach($array as $a){

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

return false;
}

1

否定のためにstrpbrk()を使用することもできます(どの文字も見つかりませんでした)。

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

1

これが私のアプローチです。一致が見つかるまで、文字列の文字を反復処理します。針の配列が大きい場合、一致が見つかったことを確認するためにすべての針をチェックする必要がないため、これは受け入れられた回答よりも優れています。

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

私はこれを受け入れられた回答に対してベンチマークし、7以上の配列で$needlesこれは劇的に高速でした。


0

次のコードで:

$flag = true;
foreach($find_letters as $letter)
    if(false===strpos($string, $letter)) {
        $flag = false; 
        break;
    }

次に、の値を確認します$flag。の場合true、すべての文字が見つかりました。そうでない場合、それはfalseです。


0

私は新しい答えを書いています。これは、私と同じように探している人を助けてくれることを願っています。

これは、「複数の針があり、それらを使用して単一の文字列を検索しようとしている」場合に機能します。これは私がそれを見つけるために出くわした質問です。

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

配列に$foundは、一致するすべての針のリストが含まれます。最も高いカウント値を持つ配列の項目が、探している文字列になります。これは、次のようにして取得できます。

print_r(array_search(max($found), $found));

0

@binyaminと@Timoに返信してください(コメントを追加するにはポイントが足りません...)。ただし、結果には位置が含まれていません。
以下のコードは、strposが意図している最初の要素の実際の位置を返します行う。これは、正確に1つの一致を見つけることを期待している場合に役立ちます。複数の一致を見つけることを期待している場合、最初に見つかった位置は意味がない場合があります。

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

0

上記の回答からのアップグレード

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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.