There are a lot of great answers here, but I want to add one more, to show a more generic approach.
function parseUnits($input, $units = array('d'=>'days','h'=>'hours','m' => 'minutes')) {
$offset = 0;
$idx = 0;
$result = array();
while(preg_match('/(\d+)(\D+)/', $input,$match, PREG_OFFSET_CAPTURE, $offset)) {
$offset = $match[2][1];
//ignore spaces
$unit = trim($match[2][0]);
if (array_key_exists($unit,$units)) {
// Check if the unit was allready found
if (isset($result[$units[$unit]])) {
throw new Exception("duplicate unit $unit");
}
// Check for corect order of units
$new_idx = array_search($unit,array_keys($units));
if ($new_idx < $idx) {
throw new Exception("unit $unit out of order");
} else {
$idx = $new_idx;
}
$result[$units[trim($match[2][0])]] = $match[1][0];
} else {
throw new Exception("unknown unit $unit");
}
}
// add missing units
foreach (array_keys(array_diff_key(array_flip($units),$result)) as $key) {
$result[$key] = 0;
}
return $result;
}
print_r(parseUnits('1d3m'));
print_r(parseUnits('8h9m'));
print_r(parseUnits('2d8h'));
print_r(parseUnits("3'4\"", array("'" => 'feet', '"' => 'inches')));
print_r(parseUnits("3'", array("'" => 'feet', '"' => 'inches')));
print_r(parseUnits("3m 5 d 5h 1M 10s", array('y' => 'years',
'm' => 'months', 'd' =>'days', 'h' => 'hours',
'M' => 'minutes', "'" => 'minutes', 's' => 'seconds' )));
print_r(parseUnits("3m 5 d 5h 1' 10s", array('y' => 'years',
'm' => 'months', 'd' =>'days', 'h' => 'hours',
'M' => 'minutes', "'" => 'minutes', 's' => 'seconds' )));
h
andm
, do it inside a loop and array_push into another array. – Edmond