Different substitution based on content

Sports Racer :

I have a need to change a suffix based on a value. My string is a number followed by specific words/letters. If the number is 24, 36, 48, 72 or, 96 and is followed by hours, hour, hrs, hr or, h then change the letters to HR.

For example 24 hours becomes 24HR or 24 hrs becomes 24HR

But, if the number is not 24, 36, 48, 72 or, 96 then change the letters to ET

240 hours becomes 240ET or 35 hours becomes 35ET

$re = '/(24|36|48|72|96)(hours|hour|hrs|hr|h)/mi';
        $subst = '$1HR';
        $iText = preg_replace($re, $subst, $iText);

This part works, but I don't know how to add in the other option of changing the text to FH. Can this be done with one pass with regex? I suspect it can, the power of regex is amazing, I'm just not that good with it.

Wiktor Stribiżew :

You may use

$rx = '~\b(?:(24|36|48|72|96)|(\d+))(h(?:(?:ou)?rs?)?)\b~i';
preg_replace_callback($rx, function($m) {
  return !empty($m[1]) ? $m[1] . 'HR' : $m[2] . 'ET';
}, $s)

See the PHP demo and the regex demo.

Details

  • \b - word boundary
  • (?:(24|36|48|72|96)|(\d+)) - a non-capturing group matching either of the two alternatives:
  • (h(?:(?:ou)?rs?)?) - Group 2: h, then an optional sequence of an optional ou, then r, then an optional s
  • \b - word boundary.

If Group 1 matches, the HR suffix is added to the number captured in Group 1, else, ET is added to the number captured in Group 2.

Full PHP demo:

$strs = ['Time 24hours','Time 36hour','Time 72hr','Time 96h','Time 24hrs','Time 35h'];
$rx = '~\b(?:(24|36|48|72|96)|(\d+))(h(?:(?:ou)?rs?)?)\b~i';
foreach ($strs as $s) {
  echo preg_replace_callback($rx, function($m) {
    return !empty($m[1]) ? $m[1] . 'HR' : $m[2] . 'ET';
  }, $s) . PHP_EOL;
}
// => Time 24HR
// Time 36HR
// Time 72HR
// Time 96HR
// Time 24HR
// Time 35ET

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=24254&siteId=1