【问题标题】:Using an array as needles in strpos在 strpos 中使用数组作为针
【发布时间】:2011-06-08 20:04:28
【问题描述】:

在搜索字符串时如何将strpos 用于指针数组?例如:

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

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

因为用这个的时候不行,要是有这样的就好了

【问题讨论】:

    标签: php arrays strpos


    【解决方案1】:

    @Dave 来自 http://www.php.net/manual/en/function.strpos.php#107351 的更新后的 sn-p

    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(string $haystack, array $needles, int $offset = 0): bool 
    {
        foreach($needles as $needle) {
            if(strpos($haystack, $query, $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
    

    【讨论】:

    • @Arnaud,你的建议是什么?
    • 我不确定,但也许我们可以从 $offset 开始在字符串中前进,并在找到第一根针时停止。想想一个充满“a”的大文本。以 $needles = [a, b] 为例。您的函数strposa 将贯穿所有文本,但这不是必需的!我可以理解吗?
    • 感谢@Arnaud 的功能建议!我完全同意您的建议的重要性,并使用改进的代码示例更新了我的答案。
    • 这不是我想说的,因为你的新函数 $needles = [b, a] 还有一个问题,此外该函数不再返回第一次出现的位置.让我再解释一下。假设字符串是“ABCDEF”,针是C和F。我们可以做的是穿过字符串:A,B...C!我们检测到 C,所以我们在这里停下来,我们可以返回第一次出现针的位置,即 2。它可以处理多个单字符串,但我没有考虑过具体的实现。跨度>
    • 我通过更改foreach($needle as $k => $query) { if(strpos($haystack, $query, $offset) !== false) return $k; }改进了代码,因此它返回了匹配项的键以供进一步处理。
    【解决方案2】:

    str_replace 要快得多。

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

    【讨论】:

    • 语法错误:第 3 行的 1 个右括号太多(由于 > 6 个字符的编辑要求,我无法直接在上面的代码中更正它;))
    • 哎呀,这太离谱了。现在修好了。为抬头干杯!
    • 最好的解决方案之一!
    • 对于问题中提出的字母数组,这可能会更快。但如果它是一组短语,那么我认为 strpos 会更胖。
    【解决方案3】:

    下面的代码不仅展示了如何做到这一点,而且还把它放在一个易于使用的函数中。它是由“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 
    

    【讨论】:

    • 我相信这只会返回它找到的第一个位置。关于如何调整它以返回大海捞针中每根针的位置的任何建议?
    【解决方案4】:

    问题是,提供的示例只是“示例”还是您要查找的内容?这里有很多混合的答案,我不明白接受的一个复杂性。

    判断字符串中是否存在ANY内容针数组,并快速返回真或假:

    $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"

    【讨论】:

    • 这对我来说非常有效,因为我正在寻找包含子字符串的数组。我免于编写诸如“%$string%”之类的sql命令
    【解决方案5】:

    如果strpos 返回false,您可以遍历数组并设置“标志”值。

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

    然后检查$flag的值。

    【讨论】:

    • 不应该是!== flase吗?
    • 应该是 !==false。除非您在将标志设置为 true 后立即中断。然后必须将该标志解释为“大海捞针”的警告。这意味着您要实现的目标是检查所有的针是否都在大海捞针中。这不是问题。嗯是的。 !== 假
    【解决方案6】:

    如果您只想检查某些字符是否确实在字符串中,请使用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)
    【解决方案7】:

    此表达式搜索所有字母:

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

    【讨论】:

      【解决方案8】:

      你可以试试这个:

      function in_array_strpos($word, $array){
      
      foreach($array as $a){
      
          if (strpos($word,$a) !== false) {
              return true;
          }
      }
      
      return false;
      }
      

      【讨论】:

        【解决方案9】:

        您也可以尝试使用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!';
        }
        

        【讨论】:

          【解决方案10】:

          这是我的方法。遍历字符串中的字符,直到找到匹配项。在更大的针阵列上,这将优于接受的答案,因为它不需要检查每根针以确定已找到匹配项。

          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 的数组,这显着更快。

          【讨论】:

            【解决方案11】:

            使用以下代码:

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

            然后检查$flag 的值。如果是true,则所有字母都已找到。如果没有,那就是false

            【讨论】:

              【解决方案12】:

              我正在写一个新的答案,希望能帮助任何寻找与我相似的人。

              这适用于“我有多个针并且我正在尝试使用它们来查找单独的字符串”的情况。这就是我遇到的问题。

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

              【讨论】:

                【解决方案13】:

                回复@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;
                }
                

                【讨论】:

                  【解决方案14】:

                  只是上述答案的升级

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

                  【讨论】:

                    【解决方案15】:
                    <?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;
                         ?>
                    

                    我用这种代码来检查你好,它还有一个编号功能。 如果您想在需要用户输入的网站中进行内容审核实践,您可以使用它

                    【讨论】:

                      【解决方案16】:

                      如果我只是想知道大海捞针是否存在,我会使用

                      可重用函数

                      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
                      

                      或 lambda 函数

                        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
                         }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2012-01-04
                        • 2011-10-17
                        • 2016-08-19
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-04-07
                        相关资源
                        最近更新 更多