是否可以像在 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
注意:应按键或值搜索
$needle="bob";
$output=array();
foreach($array as $k=>$v)
{
if(stristr($k,$needle) || stristr($v,$needle))
$output[$k]=$v;
}
print_r($output);
也就是说,如果您想同时搜索键和值,如果您只想搜索值,请删除 keys 部分。
这是一个
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
一个简单的方法是使用
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);
您想要过滤数组,请使用专门设计的
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);
$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%”的表中选择*
$data_array = array_filter($data_array , function ($item) use ($your_string) {
return strpos($item['array_key'], $your_string) !== false;
});
这将用匹配的字符串替换数组
从 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
连接在一起,但是这样你就有可能匹配任意指定的分隔字符。为了稳定性,每次迭代只需调用两次。