F21
F21

Reputation: 33391

Matching the first character from a set of matches

I have strings for date formats which will contain Y, M and D. For example some formats might be:

YY-MM-DD
M-D-Y G
MM/Y/DD
(etc)

I would like to run a regex match on strings like that and extract the Y, M, D in order. For example, in the above, I would like to have:

array('Y', 'M', 'D');
array('M', 'D', 'Y');
array('M', 'Y', 'D');
(etc)

I have written this regex expresion:

/(m+)|(d+)|(y+)/

But the issue is that it returns the whole match and not the first character like so:

array('YY', 'MM', 'DD');
array('M', 'D', 'Y');
array('MM', 'Y', 'D');
(etc)

How can I write my expression so that it only returns the first character?

Edit: some code (nothing complicated really).

$dates = array('YY-MM-DD', 'M-D-Y G', 'MM/Y/DD');

foreach($dates as $date){
   preg_match_all('/(m+)|(d+)|(y+)/', strtolower($date), $matches);
   var_dump($matches);
}

Upvotes: 2

Views: 96

Answers (4)

Alan Moore
Alan Moore

Reputation: 75222

Looks to me like /\b[ymd]/ is all you need:

$dates = array('YY-MM-DD', 'M-D-Y G', 'MM/Y/DD');

foreach($dates as $date){
   preg_match_all('/\b[ymd]/', strtolower($date), $matches);
   var_dump($matches);
}

EDIT: Here's one that handles YYYYMMDD as well:

/(?<!y)y|(?<!m)m|(?<!d)d/

output:

array(1) {
  [0]=>
  array(3) {
    [0]=>
    string(1) "y"
    [1]=>
    string(1) "m"
    [2]=>
    string(1) "d"
  }
}
array(1) {
  [0]=>
  array(3) {
    [0]=>
    string(1) "m"
    [1]=>
    string(1) "d"
    [2]=>
    string(1) "y"
  }
}
array(1) {
  [0]=>
  array(3) {
    [0]=>
    string(1) "m"
    [1]=>
    string(1) "y"
    [2]=>
    string(1) "d"
  }
}

Upvotes: 1

Daniel
Daniel

Reputation: 31579

Try making your regexp like this:

/(m)m*|(d)d*|(y)y*/

It will only capture the first letter but allow more.

Upvotes: 0

uguraslan
uguraslan

Reputation: 91

I think this one is better: collects first letter by regex. But I assume that only "-", "/" and "\" characters can appear between M,D,Y. You can add more if you need.

$dates = array('YY-MM-DD', 'M-D-Y G', 'MM/Y/DD');
$result = array();

foreach($dates as $date){

   preg_match_all('/([mdy])[a-z0-9\ \-\/\\\]?/i', $date, $matches);
   $result[] = $matches[1];

}

Upvotes: 0

uguraslan
uguraslan

Reputation: 91

I am not good at regex. But the code below can solve your problem until you find a better regex string.

$dates = array('YY-MM-DD', 'M-D-Y G', 'MM/Y/DD');
$result = array();

foreach($dates as $date){
   preg_match_all('/([m])[mdy]?|([d])[mdy]?|([y])[mdy]?/i', $date, $matches);

   $tmp = array();
   for($i=1;$i<=3;$i++){
       foreach($matches[$i] as $m){
            if(!empty($m)){
                $tmp[] = $m;
                break;
            }
       }
   }
   $result[] = $tmp;
}

Upvotes: 1

Related Questions