【问题标题】:Filter array to include all strings containing a specific word and check if any strings were matched过滤数组以包含包含特定单词的所有字符串并检查是否有任何字符串匹配
【发布时间】:2022-01-30 18:59:38
【问题描述】:

我试图从包含单词DEVICE 的数组中过滤字符串。

我使用了以下技术来检查数组中是否有一个名为“拥有设备”的单词,但它会打印出来

未找到匹配项

即使有包含单词 DEVICE 的字符串。

这是我尝试过的尝试:

$output= array('football GAME', 'cricket GAME', 'computer DEVICE','mobile DEVICE');
$string = 'DEVICE';
foreach ($output as $out) {
    if (strpos($string, $out) !== FALSE) {
        echo "Match found";
        return true;
    }
}
echo "Match Not found!";
return false;

所需输出:

输出应该是:

找到匹配项。

我还想显示由单词DEVICE 组成的项目列表,例如:

computer DEVICE  
mobile DEVICE

我需要在这里进行什么更正?

【问题讨论】:

  • 您的strpos 参数从后到前。这是strpos(string $haystack, string $needle)

标签: php arrays filtering


【解决方案1】:

解决它的一种非循环方法是使用 preg_grep,它是数组上的正则表达式。
该模式以不区分大小写的方式搜索“设备”并返回任何包含设备的字符串。

$output= array('football GAME', 'cricket GAME', 'computer DEVICE','mobile DEVICE');
$string = 'DEVICE';
$devices = preg_grep("/" . $string . "/i", $output);
Var_dump($devices);

输出

array(2) {
  [2]=>
  string(15) "computer DEVICE"
  [3]=>
  string(13) "mobile DEVICE"
}

https://3v4l.org/HkQcu

【讨论】:

  • 仅供参考,preg_grep 仍然循环:)。您可能还想通过preg_quote() 运行$string
  • @Phil 取决于你如何看待它。当你没有的时候为什么要循环?不区分大小写只是一种“猜测”,因为通常区分大小写的数组搜索不会给出您想要的结果。
  • 我的意思是在内部,它仍然在数组上循环~github.com/php/php-src/blob/master/ext/pcre/php_pcre.c#L2845。无论如何,很好的答案,它很干净
  • 当然 preg_quote 很有用。 OP 必须决定是否需要这样做。我会说所有 array_functions 循环。不同之处在于它是在内部还是在 PHP 中完成得更快,以及您发现什么最容易阅读。
【解决方案2】:

您已经交换了strpos() 中的参数。要搜索的单词是函数中的第二个参数,字符串是第一个。

int strpos (string $haystack , mixed $needle [, int $offset = 0 ])

使用下面的代码获得所需的输出:

    $output= array('football GAME', 'cricket GAME', 'computer DEVICE','mobile DEVICE');
    $string = 'DEVICE';
    foreach ($output as $out) {
        if (strpos($out, $string) !== FALSE) {
              // You can also print the matched word using the echo statement below.
              echo "Match found in word: {$out} <br/>";
              return true;
        }
    }
    echo "Match Not found!";
    return false;

【讨论】:

    【解决方案3】:

    您将 strpos 函数的参数的位置颠倒了。来自 php.net:

    int strpos (string $haystack , mixed $needle [, int $offset = 0 ])
    

    因此,您应该将第 5 行替换为以下内容

     if (strpos($out, $string) !== FALSE) {
    

    [1]https://secure.php.net/manual/en/function.strpos.php

    【讨论】:

      【解决方案4】:

      您的问题是您的 strpos() 参数是向后的。 API

      int strpos(字符串 $haystack, 混合 $needle [, int $offset = 0])


      关于你的其他问题...

      ...我还想显示由单词 DEVICE 组成的项目列表

      你可以通过array_filter()创建一个匹配元素的数组

      $string = 'DEVICE';
      $filtered = array_filter($output, function($out) use ($string) {
          return strpos($out, $string) !== false;
      });
      
      echo implode(PHP_EOL, $filtered);
      if (count($filtered) > 0) {
          echo 'Match found';
          return true;
      }
      echo 'Match Not found!';
      return false;
      

      【讨论】:

        【解决方案5】:

        如果您想访问过滤后的数组(包含 DEVICE 的字符串),那么您将无法再享受早期 return 的性能优势。您必须迭代整个输入数组——使用经典循环或数组迭代函数。我必须声明,您的要求不需要正则表达式的力量;迭代的正则表达式评估应该保留在更简单的原生字符串函数不太适合的情况下。

        归根结底,您需要反复进行区分大小写的检查,并包含包含您的限定关键字的字符串。

        从 PHP7.4 开始,箭头函数允许更简洁的匿名函数语法,并允许省略 use() 调用。

        从 PHP8 开始,str_contains() 可用,非常适合您所需的匹配。

        要找出是否有任何字符串符合条件,只需检查输出数组的布尔值。

        代码:(Demo)

        $input= [
            'football GAME',
            'cricket GAME',
            'computer DEVICE',
            'mobile DEVICE'
        ];
        $needle = 'DEVICE';
        
        $output = array_filter($input, fn($haystack) => str_contains($haystack, $needle));
        
        var_export(
            [
                'filtered' => $output,
                'found' => $output ? 'yes' : 'no'
            ]
        );
        

        输出:

        array (
          'filtered' => 
          array (
            2 => 'computer DEVICE',
            3 => 'mobile DEVICE',
          ),
          'found' => 'yes',
        )
        

        【讨论】:

          猜你喜欢
          • 2013-12-23
          • 2016-02-24
          • 1970-01-01
          • 1970-01-01
          • 2011-05-20
          相关资源
          最近更新 更多