Verwenden eines Arrays als Nadeln in Strpos


89

Wie verwenden Sie die strposfür eine Reihe von Nadeln, wenn Sie eine Zeichenfolge suchen? Beispielsweise:

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

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

Denn wenn man das benutzt, würde es nicht funktionieren, es wäre gut, wenn es so etwas gäbe

Antworten:


134

@Dave ein aktualisiertes Snippet von 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);
}

Wie benutzt man:

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

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

wird truewegen zurückkehren array "cheese".

Update: Verbesserter Code mit Stopp, wenn die erste der Nadeln gefunden wird:

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, was ist Ihr vorgeschlagenes Gerät?
Binyamin

5
Ich bin mir nicht sicher, aber vielleicht könnten wir von $ offset in der Zeichenfolge vorrücken und aufhören, wenn die erste der Nadeln gefunden wird. Denken Sie an einen großen Text voller "a". Nimm $ Nadeln = [a, b]. Ihre Funktion strposadurchläuft den gesamten Text, ist aber nicht erforderlich! Bin ich verständlich
Arnaud

Vielen Dank an @Arnaud für den Funktionsvorschlag! Ich stimme Ihrer Wichtigkeit als Vorschlag voll und ganz zu und habe meine Antwort mit einem verbesserten Codebeispiel aktualisiert.
Binyamin

Dies ist nicht genau das, was ich sagen wollte, denn mit Ihrer neuen Funktion hat $ Needles = [b, a] noch ein Problem und außerdem gibt die Funktion nicht mehr die Position des ersten Auftretens zurück. Lassen Sie mich etwas mehr erklären. Angenommen, die Zeichenfolge ist "ABCDEF" und die Nadeln sind C und F. Wir könnten die Zeichenfolge durchlaufen: A, B ... C! Wir erkennen C, also hören wir hier auf und können die Position des ersten Auftretens einer Nadel zurückgeben, nämlich 2. Es könnte mit mehr als einstelligen Zeichenfolgen funktionieren, aber ich habe nicht über die genaue Implementierung nachgedacht.
Arnaud

1
Ich habe den Code durch Ändern verbessert foreach($needle as $k => $query) { if(strpos($haystack, $query, $offset) !== false) return $k; }, sodass der Schlüssel des übereinstimmenden Elements zur weiteren Bearbeitung zurückgegeben wird.
James Cameron

48

str_replace ist erheblich schneller.

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

Syntaxfehler: 1 schließende Klammer zu viel in Zeile 3 (ich konnte es nicht direkt im obigen Code korrigieren, da> 6 Zeichen bearbeitet werden müssen;))
richey

1
Ups, das war von der Manschette. Jetzt behoben. Prost auf die Köpfe hoch!
Leon

4
eine der besten lösungen!
Andys

18

Der folgende Code zeigt nicht nur, wie es geht, sondern bringt es auch in eine benutzerfreundliche Funktion, die sich weiterentwickelt. Es wurde von "jesda" geschrieben. (Ich habe es online gefunden)

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

Verwendung:

$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 

Ich glaube, dies gibt nur die 1. Position zurück, die es findet. Irgendwelche Vorschläge, wie man es optimiert, um die Position jeder Nadel im Heuhaufen wiederherzustellen?
Chaya Cooper

7

Sie können das Array durchlaufen und bei strposRückgabe einen "Flag" -Wert festlegen false.

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

Überprüfen Sie dann den Wert von $flag.


6
sollte es nicht sein !== flase?
Joe Huang

Es sollte sein! == false. Es sei denn, Sie brechen sofort, nachdem Sie Ihr Flag auf true gesetzt haben. Und dann müsste die Flagge als Warnung interpretiert werden, dass sich eine Nadel nicht im Heuhaufen befindet. Das bedeutet, dass Sie versuchen zu überprüfen, ob sich alle Ihre Nadeln im Heuhaufen befinden. Welches ist nicht die Frage. Also ... ja. ! == false
Kevin Gagnon

5

Wenn Sie nur überprüfen möchten, ob bestimmte Zeichen tatsächlich in der Zeichenfolge enthalten sind oder nicht, verwenden Sie strtok :

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

Unglaubliche Antwort - VIEL schnellere Ausführung als mehrere strpos (), z. B. if (strpos ($ string, "a")! == false && strpos ($ string, "c")! == false && strpos ($ string, " d ")! == false)
The One and Only ChemistryBlob

5

Die Frage, ist das bereitgestellte Beispiel nur ein "Beispiel" oder genau das, wonach Sie suchen? Hier gibt es viele gemischte Antworten, und ich verstehe die Komplexität der akzeptierten nicht.

Um herauszufinden, ob JEDER Inhalt des Nadelarrays in der Zeichenfolge vorhanden ist, und schnell true oder false zurückzugeben:

$string = 'abcdefg';

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

Wenn ja, geben Sie @Leon dies bitte gut .

Um herauszufinden, ob ALLE Werte des Nadelarrays in der Zeichenfolge vorhanden sind, MÜSSEN in diesem Fall alle drei 'a', 'b'und 'c'MÜSSEN vorhanden sein, wie Sie als "Beispiel" angeben.

echo 'Alle Buchstaben sind in der Zeichenfolge gefunden!';

Viele Antworten hier sind nicht in diesem Zusammenhang, aber ich bezweifle, dass die Intensität der Frage, die Sie als gelöst markiert haben. ZB Die akzeptierte Antwort ist eine Nadel von

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

Was ist, wenn all diese Wörter in der Zeichenfolge gefunden werden müssen?

Dann probieren Sie einige "not accepted answers"auf dieser Seite aus.


Dies funktionierte perfekt für mich, da ich sah, dass mein Array Unterstrings enthielt. Ich wurde vom Schreiben eines SQL-Befehls wie "% $ string%"
Maurice Elagu

4

Dieser Ausdruck sucht nach allen Buchstaben:

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

3

Sie können dies versuchen:

function in_array_strpos($word, $array){

foreach($array as $a){

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

return false;
}

1

Sie können auch versuchen, strpbrk () für die Negation zu verwenden (keiner der Buchstaben wurde gefunden):

$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

Das ist mein Ansatz. Durchlaufen Sie die Zeichen in der Zeichenfolge, bis eine Übereinstimmung gefunden wird. Bei einer größeren Anzahl von Nadeln übertrifft dies die akzeptierte Antwort, da nicht jede Nadel überprüft werden muss, um festzustellen, ob eine Übereinstimmung gefunden wurde.

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

Ich habe dies mit der akzeptierten Antwort verglichen und mit einer Reihe von mehr als 7 war $needlesdies dramatisch schneller.


0

Mit folgendem Code:

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

Überprüfen Sie dann den Wert von $flag. Wenn ja true, wurden alle Buchstaben gefunden. Wenn nicht, ist es false.


0

Ich schreibe eine neue Antwort, die hoffentlich jedem hilft, der nach dem sucht, was ich bin.

Dies funktioniert im Fall von "Ich habe mehrere Nadeln und ich versuche, sie zu verwenden, um eine einzelne Schnur zu finden". und das ist die Frage, auf die ich gestoßen bin, um das zu finden.

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

Das Array $foundenthält eine Liste aller übereinstimmenden Nadeln. Das Element des Arrays mit dem höchsten Zählwert ist die gesuchte Zeichenfolge. Sie können diese erhalten mit:

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

0

Antworte auf @binyamin und @Timo .. (nicht genug Punkte, um einen Kommentar hinzuzufügen ..), aber das Ergebnis enthält nicht die Position ..
Der folgende Code gibt die tatsächliche Position des ersten Elements zurück, für das strpos bestimmt ist machen. Dies ist nützlich, wenn Sie genau 1 Übereinstimmung erwarten. Wenn Sie mehrere Übereinstimmungen erwarten, ist die Position der zuerst gefundenen möglicherweise bedeutungslos.

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

Nur ein Upgrade von oben Antworten

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;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.