ใช้อาร์เรย์เป็นเข็มใน strpos


96

คุณใช้strposสำหรับอาร์เรย์ของเข็มเมื่อค้นหาสตริงได้อย่างไร? ตัวอย่างเช่น:

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

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

เพราะเมื่อใช้สิ่งนี้มันจะไม่ได้ผลมันคงจะดีถ้ามีอะไรแบบนี้

คำตอบ:


140

@ บันทึกข้อมูลโค้ดที่อัปเดตจาก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" รับ $ เข็ม = [a, b] ฟังก์ชันของคุณstrposaจะทำงานผ่านข้อความทั้งหมด แต่ไม่จำเป็น! ฉันเข้าใจไหม
Arnaud

ขอบคุณ @Arnaud สำหรับคำแนะนำคุณสมบัติ! ฉันเห็นด้วยกับความสำคัญของข้อเสนอแนะของคุณและได้อัปเดตคำตอบของฉันด้วยตัวอย่างโค้ดที่ปรับปรุงแล้ว
Binyamin

นี่ไม่ใช่สิ่งที่ฉันต้องการจะพูดอย่างแน่นอนเพราะด้วยฟังก์ชันใหม่ของคุณ $ เข็ม = [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

60

str_replace เร็วกว่ามาก

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

ข้อผิดพลาดทางไวยากรณ์: 1 วงเล็บปิดมากเกินไปที่บรรทัด # 3 (ฉันไม่สามารถแก้ไขได้โดยตรงในโค้ดด้านบนเนื่องจากข้อกำหนดการแก้ไขอักขระ> 6 ตัว;))
richey

1
อ๊ะนั่นคือการปิดแขนเสื้อ แก้ไขแล้ว ไชโย!
Leon

8
หนึ่งในทางออกที่ดีที่สุด!
andys

19

โค้ดด้านล่างนี้ไม่เพียง แต่แสดงวิธีการทำเท่านั้น แต่ยังทำให้ฟังก์ชันที่ใช้งานง่ายก้าวไปข้างหน้าอีกด้วย เขียนโดย "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 

ฉันเชื่อว่านี่จะส่งคืนตำแหน่งที่ 1 ที่พบเท่านั้น มีข้อเสนอแนะเกี่ยวกับวิธีปรับแต่งเพื่อคืนตำแหน่งของเข็มทุกเข็มในกองหญ้าหรือไม่?
Chaya Cooper

7

คุณสามารถย้ำผ่านอาร์เรย์และตั้งเป็น "ธง" ค่าถ้าผลตอบแทนstrposfalse

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

จากนั้นตรวจสอบค่าของ$flag.


6
มันไม่ควร!== flase?
Joe Huang

มันควรจะเป็น! == เท็จ เว้นแต่คุณจะพังทันทีหลังจากตั้งค่าสถานะเป็นจริง จากนั้นจะต้องตีความธงว่าเป็นคำเตือนว่าเข็มไม่ได้อยู่ในกองหญ้า นั่นหมายความว่าสิ่งที่คุณพยายามจะบรรลุคือการตรวจสอบว่าเข็มทั้งหมดของคุณอยู่ในกองหญ้า ซึ่งไม่ใช่คำถาม ใช่แล้ว .. ! == false
Kevin Gagnon

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)
The One and Only ChemistryBlob

5

คำถามตัวอย่างที่ให้มาเป็นเพียง "ตัวอย่าง" หรือสิ่งที่คุณกำลังมองหากันแน่? มีคำตอบหลายคำตอบที่นี่และฉันไม่เข้าใจความซับซ้อนของคำตอบที่ยอมรับ

หากต้องการค้นหาว่าใด ๆเนื้อหาของอาร์เรย์ของเข็มอยู่ในสตริงและรวดเร็วกลับเท็จจริงหรือ:

$string = 'abcdefg';

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

ถ้าเป็นเช่นนั้นโปรดให้เครดิต@Leonสำหรับสิ่งนั้น

หากต้องการทราบว่าค่าทั้งหมดของอาร์เรย์ของเข็มมีอยู่ในสตริงหรือไม่เช่นในกรณีนี้ต้องมีทั้งสาม'a', 'b'และ'c'ต้องมีอยู่เช่นที่คุณกล่าวถึงเป็น "ตัวอย่าง" ของคุณ

echo 'พบตัวอักษรทั้งหมดในสตริง!';

คำตอบมากมายที่นี่ไม่อยู่ในบริบทนั้น แต่ฉันสงสัยว่าความตั้งใจของคำถามที่คุณทำเครื่องหมายว่าได้รับการแก้ไขแล้ว เช่นคำตอบที่ยอมรับคือเข็มของ

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

จะเป็นอย่างไรหากต้องพบคำเหล่านั้นในสตริง

จากนั้นให้คุณลองใช้งาน"not accepted answers"ในหน้านี้


สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบสำหรับฉันเนื่องจากฉันมองว่าอาร์เรย์ของฉันมีสตริงย่อย ฉันได้รับการบันทึกจากการเขียนคำสั่ง sql เช่น "% $ string%"
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

นี่คือแนวทางของฉัน วนซ้ำอักขระในสตริงจนกว่าจะพบรายการที่ตรงกัน สำหรับเข็มที่มีขนาดใหญ่กว่านี้จะมีประสิทธิภาพดีกว่าคำตอบที่ได้รับการยอมรับเนื่องจากไม่จำเป็นต้องตรวจสอบทุกเข็มเพื่อตรวจสอบว่าพบการจับคู่แล้ว

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

ฉัน benchmarked นี้กับคำตอบที่ได้รับการยอมรับและมีมากมายกว่า 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;
}

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

ฉันใช้รหัสประเภทนี้เพื่อตรวจสอบสวัสดีและยังมีคุณลักษณะการกำหนดหมายเลข คุณสามารถใช้สิ่งนี้ได้หากคุณต้องการทำแนวปฏิบัติในการกลั่นกรองเนื้อหาในเว็บไซต์ที่ต้องให้ผู้ใช้พิมพ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.