66

How do I search in an array with preg_match?

Example:

<?php
if( preg_match( '/(my\n+string\n+)/i' , array( 'file' , 'my string  => name', 'this') , $match) )
{
    //Excelent!!
    $items[] = $match[1];
} else {
    //Ups! not found!
}
?>
Olaf Erlandsen
  • 5,817
  • 9
  • 41
  • 73

6 Answers6

194

In this post I'll provide you with three different methods of doing what you ask for. I actually recommend using the last snippet, since it's easiest to comprehend as well as being quite neat in code.

How do I see what elements in an array that matches my regular expression?

There is a function dedicated for just this purpose, preg_grep. It will take a regular expression as first parameter, and an array as the second.

See the below example:

$haystack = array (
  'say hello',
  'hello stackoverflow',
  'hello world',
  'foo bar bas'
);

$matches  = preg_grep ('/^hello (\w+)/i', $haystack);

print_r ($matches);

output

Array
(
    [1] => hello stackoverflow
    [2] => hello world
)

Documentation


But I just want to get the value of the specified groups. How?

array_reduce with preg_match can solve this issue in clean manner; see the snippet below.

$haystack = array (
  'say hello',
  'hello stackoverflow',
  'hello world',
  'foo bar bas'
);

function _matcher ($m, $str) {
  if (preg_match ('/^hello (\w+)/i', $str, $matches))
    $m[] = $matches[1];

  return $m;
}

// N O T E :
// ------------------------------------------------------------------------------
// you could specify '_matcher' as an anonymous function directly to
// array_reduce though that kind of decreases readability and is therefore
// not recommended, but it is possible.

$matches = array_reduce ($haystack, '_matcher', array ());

print_r ($matches);

output

Array
(
    [0] => stackoverflow
    [1] => world
)

Documentation


Using array_reduce seems tedious, isn't there another way?

Yes, and this one is actually cleaner though it doesn't involve using any pre-existing array_* or preg_* function.

Wrap it in a function if you are going to use this method more than once.

$matches = array ();

foreach ($haystack as $str) 
  if (preg_match ('/^hello (\w+)/i', $str, $m))
    $matches[] = $m[1];

Documentation

Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
8

Use preg_grep

$array = preg_grep(
    '/(my\n+string\n+)/i',
    array( 'file' , 'my string  => name', 'this')
);
Galen
  • 29,976
  • 9
  • 71
  • 89
7
$haystack = array (
   'say hello',
   'hello stackoverflow',
   'hello world',
   'foo bar bas'
);

$matches  = preg_grep('/hello/i', $haystack);

print_r($matches);

Output:

Array
(
   [1] => say hello
   [2] => hello stackoverflow
   [3] => hello world
)
Mahdi Bashirpour
  • 17,147
  • 12
  • 117
  • 144
4

You can use array_walk to apply your preg_match function to each element of the array.

http://us3.php.net/array_walk

Logan Serman
  • 29,447
  • 27
  • 102
  • 141
  • This seems overly complicated for this task. Youd have to use the callback to delete the non-matchign items. – Galen Dec 24 '11 at 23:11
3
$items = array();
foreach ($haystacks as $haystack) {
    if (preg_match($pattern, $haystack, $matches)
        $items[] = $matches[1];
}
goat
  • 31,486
  • 7
  • 73
  • 96
0

may be a little longer but I can offer you this version!


$array = array (
    'tagid=1' => '1',
    "a" => "a", 
    "b" => "b", 
    "c" => "c",
    'tagid=2' => '2',
);

$regex = '/tagid=[0-9]+/i';

$tags = [];

foreach ($data as $key => $value) {
    if (preg_match($regex, $key)) {
        $tags[] = $value;
    }
}

// OUTPUT
$tags = array (
    0 => '1',
    1 => '2'
);