1

I am currently working on a small script to convert data coming from an external source. Depending on the content I need to map this data to something that makes sense to my application.

A sample input could be:

$input = 'We need to buy paper towels.'

Currently I have the following approach:

// Setup an assoc_array what regexp match should be mapped to which itemId
private $itemIdMap = [ '/paper\stowels/' => '3746473294' ];

// Match the $input ($key) against the $map and return the first match
private function getValueByRegexp($key, $map) {
  $match = preg_grep($key, $map);
  if (count($match) > 0) {
    return $match[0];
  } else {
    return '';
  }
}

This raises the following error on execution:

Warning: preg_grep(): Delimiter must not be alphanumeric or backslash

What am I doing wrong and how could this be solved?

Severin
  • 8,508
  • 14
  • 68
  • 117

1 Answers1

2

In preg_grep manual order of arguments is:

string $pattern , array $input

In your code $match = preg_grep($key, $map); - $key is input string, $map is a pattern.

So, your call is

$match = preg_grep(
    'We need to buy paper towels.', 
    [ '/paper\stowels/' => '3746473294' ] 
);

So, do you really try to find string We need to buy paper towels in a number 3746473294?

So first fix can be - swap'em and cast second argument to array:

$match = preg_grep($map, array($key));

But here comes second error - $itemIdMap is array. You can't use array as regexp. Only scalar values (more strictly - strings) can be used. This leads you to:

$match = preg_grep($map['/paper\stowels/'], $key);

Which is definitely not what you want, right?

The solution:

$input = 'We need to buy paper towels.';
$itemIdMap = [
    '/paper\stowels/' => '3746473294',
    '/other\sstuff/' => '234432',
    '/to\sbuy/' => '111222',
];

foreach ($itemIdMap as $k => $v) {
    if (preg_match($k, $input)) {
        echo $v . PHP_EOL;
    }
}

Your wrong assumption is that you think you can find any item from array of regexps in a single string with preg_grep, but it's not right. Instead, preg_grep searches elements of array, which fit one single regexp. So, you just used the wrong function.

u_mulder
  • 54,101
  • 5
  • 48
  • 64