0

I have a file with some data in the format of:

0101    Group1  01/13/13
0102    Group1  02/03/13
0103    Group1  03/05/13
0104    Group1  04/05/13
0201    Group2  04/19/13
0202    Group2  05/10/13
0301    Group3  07/13/13
0302    Group3  07/13/13
0303    Group3  07/13/13
0401    Group4  02/12/13
0501    Group5  05/29/13

I only have a total of 5 Groups. I am trying to replace each Group with a single letter value here.

Group1 will be replaced with A
Group2 will be replaced with B
Group3 will be replaced with C
Group4 will be replaced with D
Group5 will be replaced with E

I found a way to do this with preg_replace_callback.

$text = preg_replace_callback('/Group[1-5]/', 'id_callback', $text);

function id_callback($matches) {
  if ($matches[0] == 'Group1') {
    return 'A';
  } elseif ($matches[0] == 'Group2') {
    return 'B';
  } elseif ($matches[0] == 'Group3') {
    return 'C';
  } elseif ($matches[0] == 'Group4') {
    return 'D';
  } elseif ($matches[0] == 'Group5') {
    return 'E';
  }
}

echo $text;

Is there a way I can do this and get rid of all these if statements?

3 Answers 3

2

Mathematical relationships are a great help.

$text = preg_replace_callback("/Group([1-5])/",function($m) {
    return chr(ord("A")+$m[1]-1);
},$text);
Sign up to request clarification or add additional context in comments.

2 Comments

neat, i was writing an answer using an array, but this is cuter
There shouldn't be a place for "Cute" in programming IMO, clarity is where the beauty is at. :)
2

A different approach for this would incline using an associative array with either an anonymous/named function leading to running the callback for every match that it finds and populating the match with the value from the array.

$map = array('Group1' => 'A', 'Group2' => 'B', 
             'Group3' => 'C', 'Group4' => 'D', 'Group5' => 'E');

$text = preg_replace_callback('/(?P<id>Group[1-5])/', 
      function($m) {
          global $map; 
          extract($m);
          return isset($map[$id]) ? $map[$id] : $m[0];
      }, $text);

Note: I replaced your regular expression with a Named capturing Group for readabilty.

Update

As mentioned by @Niet the Dark Absol, here's a simple way to perform this using strtr to replace.

$text = _replace($text);

function _replace($t) {
  $map = array('Group1' => 'A', 'Group2' => 'B', 
               'Group3' => 'C', 'Group4' => 'D', 'Group5' => 'E'
  );
  return strtr($t, $map);
}

3 Comments

Instead of global, you can use function($m) use ($map) syntax for anonymous functions.
If you're starting with the associative array, why not use the cheaper strtr to perform the swap?
Thanks, I forgot about that
1

Yes:

$find = array('Group1', 'Group2', 'Group3', 'Group4', 'Group5');
$replace = array('A', 'B', 'C', 'D', 'E');
$result = str_replace($find, $replace, $string);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.