user3530525
user3530525

Reputation: 691

preg_match() match to cases with one pattern?

How would I go about ordering 1 array into 2 arrays depending on what each part of the array starts with using preg_match() ?

I know how to do this using 1 expression but I don't know how to use 2 expressions. So far I can have done (don't ask why I'm not using strpos() - I need to use regex):

$gen =  array(
    'F1',
    'BBC450',
    'BBC566',
    'F2',
    'F31',
    'SOMETHING123',
    'SOMETHING456'
);

$f = array();
$bbc = array();

foreach($gen as $part) {
    if(preg_match('/^F/', $part)) {
        // Add to F array
        array_push($f, $part);
    } else if(preg_match('/^BBC/', $part)) {
        // Add to BBC array
       array_push($bbc, $part);
    } else {
        // Not F or BBC
    }
}

So my question is: is it possible to do this using 1 preg_match() function? Please ignore the SOMETHING part in the array, it's to show that using just one if else statement wouldn't solve this.

Thanks.

Upvotes: 1

Views: 335

Answers (2)

Fleshgrinder
Fleshgrinder

Reputation: 16273

It is even possible without any loop, switch, or anything else (which is faster and more efficient then the accepted answer's solution).

<?php

preg_match_all("/(?:(^F.*$)|(^BBC.*$))/m", implode(PHP_EOL, $gen), $matches);

$f = isset($matches[1]) ? $matches[1] : array();
$bbc = isset($matches[2]) ? $matches[2] : array();

You can find an interactive explanation of the regular expression at regex101.com which I created for you.


The (not desired) strpos approach is nearly five times faster.

<?php

$c = count($gen);
$f = $bbc = array();
for ($i = 0; $i < $c; ++$i) {
  if (strpos($gen[$i], "F") === 0) {
    $f[] = $gen[$i];
  }
  elseif (strpos($gen[$i], "BBC") === 0) {
    $bbc[] = $gen[$i];
  }
}

Regular expressions are nice, but the are no silver bullet for everything.

Upvotes: 1

Barmar
Barmar

Reputation: 781210

You can use an alternation along with the third argument to preg_match, which contains the part of the regexp that matched.

preg_match('/^(?:F|BBC)/', $part, $match);
switch ($match) {
case 'F':
    $f[] = $part;
    break;
case 'BBC':
    $bbc[] = $part;
    break;
default:
    // Not F or BBC
}

Upvotes: 3

Related Questions