通过搜索键和值中的部分匹配来过滤数组元素

问题描述 投票:0回答:7

是否可以像在 MySQL 中一样在 PHP 数组中进行搜索。

例如:我有这个

array

array(
  '[email protected]'=> `Mark Mian`,
  '[email protected]'=> `John jack`,
  '[email protected]'=> `Bob Logon`,
  '[email protected]'=> `Stela Josh`,
  '[email protected]'=> `Json Josh`
  '[email protected]'=> `Bob Mark`
)

我会做这种类型的搜索,

例如:如果我搜索

Mark
,它应该返回给我这个

'[电子邮件受保护]' => `马克·勉

如果我搜索

Bob
它应该返回我

'[电子邮件受保护]'=>

Bob Mark

'[电子邮件受保护]'=>

Bob Logon
,

如果我只搜索

a
,它应该返回那些包含
a
的元素,例如:

'[电子邮件受保护]'=>

Mark Mian
,

'[电子邮件受保护]'=>

John jack
,

'[电子邮件受保护]'=>

Stela Josh
,

'[电子邮件受保护]'=>

Bob Mark

注意:应按键或值搜索

php arrays regex search filtering
7个回答
7
投票
$needle="bob";
$output=array();
foreach($array as $k=>$v)
{
   if(stristr($k,$needle) || stristr($v,$needle))
   $output[$k]=$v;
}
print_r($output);

小提琴

也就是说,如果您想同时搜索键和值,如果您只想搜索值,请删除 keys 部分。


6
投票

这是一个

preg_grep
解决方案,应该更像 MySQL 中的
WHERE REGEXP 'PATTERN'
。我修改了 Daniel Klein 的
preg_grep_keys
函数
来搜索数组键中的模式,并向其添加了
array_merge
,它应该适用于具有非数字键的数组。如果键是数字,只需使用
preg_grep
解决方案
preg_grep('~Mark~i', $arr);
查找所有具有
mark
Mark
等的数组元素)。

array_merge

将一个或多个数组的元素合并在一起,以便将其中一个的值附加到前一个数组的末尾。它返回结果数组。 如果输入数组具有相同的字符串键,则该键的后一个值将覆盖前一个值。但是,如果数组包含数字键,则后一个值将不会覆盖原始值,而是会追加。

function preg_grep_keys_values($pattern, $input, $flags = 0) {
    return array_merge(
      array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags))),
      preg_grep($pattern, $input, $flags)
   );
}

$a = array(
  '[email protected]'=> "Mark Mian lv",
  '[email protected]'=> "John jack lv",
  '[email protected]'=> "Bob Logon",
  '[email protected]'=> "Stela Josh",
  '[email protected]'=> "Json Josh",
  '[email protected]'=> "Bob Mark"
);

$r = preg_grep_keys_values('~lv~i', $a);
print_r($r);

参见 这个 IDEONE 演示

上面的代码首先在键中搜索

lv
(不区分大小写),然后在值中搜索,然后将结果合并到 1 个数组中。因此,结果是:

[[email protected]] => John jack lv
[[email protected]] => Bob Mark
[[email protected]] => Mark Mian lv

4
投票

一个简单的方法是使用

array_filter

如果你想要正则表达式,这会起作用

$regex = '~test~';
$result = array_filter($data, function($item) use ($regex) {
    return preg_match($regex, $item);
});

或者只是一个简单的包含搜索

$search = 'test';
$result = array_filter($data, function($item) use ($search) {
    return stristr($value, $search);
});

如果您必须同时搜索键和值,您可以将参数

ARRAY_FILTER_USE_BOTH
附加到array_filter。

$search = 'test';
$result = array_filter($data, function($item, $key) use ($search) {
    return stristr($value, $search) || stristr($key, $search);
}, ARRAY_FILTER_USE_BOTH);

最后,您可以将 array_filter 与 preg_grep 结合起来一次搜索两者。

$search = '~bob~i';
$result = array_filter($data, function() use ($search) {
    return count(preg_grep($search, func_get_args()));
}, ARRAY_FILTER_USE_BOTH);

2
投票

您想要过滤数组,请使用专门设计的

array_filter

如果您只搜索文字字符串,则不需要使用正则表达式:

$needle = 'bob';

$result = array_filter($data, function ($k, $v) use ($needle) {
    return stripos($k, $needle) !== false || stripos($v, $needle) !== false;
}, ARRAY_FILTER_USE_BOTH);

如果您希望能够使用正则表达式进行过滤:

$pattern = '~n.*e~i';

$result = array_filter($data, function ($k, $v) use ($pattern) {
    return !empty(preg_grep($pattern, [$k, $v]));
}, ARRAY_FILTER_USE_BOTH);

0
投票
   $search = "Mark"

  $array = array(
  '[email protected]'=> `Mark Mian`,
 '[email protected]'=> `John jack`,
 '[email protected]'=> `Bob Logon`,
 '[email protected]'=> `Stela Josh`,
 '[email protected]'=> `Json Josh`
'[email protected]'=> `Bob Mark`
 )
       foreach ($array as $key => $value) {
         if (stristr($value, $search) == '') {
        //not found
        }else{
      //found
       }

这是搜索任何子字符串的最佳方法,不区分大小写且快速

就像mysql中一样

例如:

从名称=“%Mark%”的表中选择*


0
投票
$data_array = array_filter($data_array , function ($item) use ($your_string) {
            return strpos($item['array_key'], $your_string) !== false;
        });

这将用匹配的字符串替换数组


0
投票

从 PHP8 开始,

str_contain()
成为首选本机函数,以简化语法进行区分大小写的搜索。

搜索小写字母

b
很好地演示了对键和值的区分大小写的搜索。

代码:(演示

$array = [
    '[email protected]'=> "Mark Mian lv",
    '[email protected]'=> "John jack lv",
    '[email protected]'=> "Bob Logon",
    '[email protected]'=> "Stela Josh",
    '[email protected]'=> "Json Josh",
    '[email protected]'=> "Bob Mark"
];

$needle = 'b';

var_export(
    array_filter(
        $array,
        fn($v, $k) => str_contains($v, $needle) || str_contains($k, $needle),
        ARRAY_FILTER_USE_BOTH
    )
);

输出:

array (
  '[email protected]' => 'Mark Mian lv',
  '[email protected]' => 'Bob Logon',
  '[email protected]' => 'Bob Mark',
)

如果你想变得可爱并在

array_filter()
内部进行单个函数调用,那么你可以将
$v
$k
连接在一起,但是这样你就有可能匹配任意指定的分隔字符。为了稳定性,每次迭代只需调用两次。

© www.soinside.com 2019 - 2024. All rights reserved.