Created
July 5, 2016 15:57
-
-
Save marcojetson/01fd378d0e2baad5a8ed4ce13ed32180 to your computer and use it in GitHub Desktop.
Extract and reduce measurement units from strings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require __DIR__ . '/strtounits.php'; | |
assert(strtometers('25000.23 meters') === 25000.23); | |
assert(strtometers('3km, 25.5 meters') === 3025.5); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @param string $str | |
* @return array | |
*/ | |
function strtounits($str) | |
{ | |
$locale = localeconv(); | |
$units = [ | |
'k' => 'k', | |
'km' => 'k', | |
'kms' => 'k', | |
'kilometer' => 'k', | |
'kilometers' => 'k', | |
'm' => 'm', | |
'ms' => 'm', | |
'meter' => 'm', | |
'meters' => 'm', | |
'c' => 'c', | |
'cm' => 'c', | |
'cms' => 'c', | |
'centimeter' => 'c', | |
'centimeters' => 'c', | |
]; | |
$re = '/(?P<value>\d{1,3}(?:' . (empty($locale['thousands_sep']) ? '' : '\\' . $locale['thousands_sep'] . '?') . '\d{3})*(?:\\' . $locale['decimal_point'] . '\d+)?)\s*(?P<unit>' . join ('|', array_keys($units)) . ')/'; | |
$count = preg_match_all($re, $str, $matches); | |
if ($count === 0) { | |
return false; | |
} | |
$result = []; | |
for ($i = 0; $i < $count; $i++) { | |
$unit = $units[$matches['unit'][$i]]; | |
$value = str_replace($locale['thousands_sep'], '', $matches['value'][$i]); | |
if (!isset($result[$unit])) { | |
$result[$unit] = 0; | |
} | |
$result[$unit] += $value; | |
} | |
return $result; | |
} | |
/** | |
* @param string $str | |
* @return float | |
*/ | |
function strtounit($str, array $multipliers) | |
{ | |
$units = strtounits($str); | |
if ($units === false) { | |
return false; | |
} | |
$result = 0; | |
foreach ($units as $unit => $value) { | |
if (!isset($multipliers[$unit])) { | |
continue; | |
} | |
$result += $value * $multipliers[$unit]; | |
} | |
return $result; | |
} | |
/** | |
* @param string $str | |
* @return float | |
*/ | |
function strtokilometers($str) | |
{ | |
return strtounit($str, [ | |
'k' => 1, | |
'm' => 0.01, | |
'c' => 0.00001, | |
]); | |
} | |
/** | |
* @param string $str | |
* @return float | |
*/ | |
function strtometers($str) | |
{ | |
return strtounit($str, [ | |
'k' => 1000, | |
'm' => 1, | |
'c' => 0.01, | |
]); | |
} | |
/** | |
* @param string $str | |
* @return float | |
*/ | |
function strtocentimeters($str) | |
{ | |
return strtounit($str, [ | |
'k' => 100000, | |
'm' => 100, | |
'c' => 1, | |
]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment