Here I am faced with an issue that I believe(or at least hope) was solved 1 million times already. What I got as the input is a string that represents a length of an object in imperial units. It can go like this:
$length = "3' 2 1/2\"";
or like this:
$length = "1/2\"";
or in fact in any other way we normally would write it.
In effort to reduce global wheel invention, I wonder if there is some function, class, or regexp-ish thing that will allow me to convert Imperial length into Metric length?
Here is my solution. It uses eval() to evaluate the expression, but don't worry, the regex check at the end makes it completely safe.
function imperial2metric($number) {
// Get rid of whitespace on both ends of the string.
$number = trim($number);
// This results in the number of feet getting multiplied by 12 when eval'd
// which converts them to inches.
$number = str_replace("'", '*12', $number);
// We don't need the double quote.
$number = str_replace('"', '', $number);
// Convert other whitespace into a plus sign.
$number = preg_replace('/\s+/', '+', $number);
// Make sure they aren't making us eval() evil PHP code.
if (preg_match('/[^0-9\/\.\+\*\-]/', $number)) {
return false;
} else {
// Evaluate the expression we've built to get the number of inches.
$inches = eval("return ($number);");
// This is how you convert inches to meters according to Google calculator.
$meters = $inches * 0.0254;
// Returns it in meters. You may then convert to centimeters by
// multiplying by 100, kilometers by dividing by 1000, etc.
return $meters;
}
}
So for example, the string
3' 2 1/2"
gets converted to the expression
3*12+2+1/2
which gets evaluated to
38.5
which finally gets converted to 0.9779 meters.
The Zend Framework has a measurement component for just that purpose. I suggest you check it out - here.
$unit = new Zend_Measure_Length($length,Zend_Measure_Length::YARD);
$unit -> convertTo(Zend_Measure_Length::METER);
The imperial string values are a little bit more complicated, so I used following expression:
string pattern = "(([0-9]+)')*\\s*-*\\s*(([0-9])*\\s*([0-9]/[0-9])*\")*";
Regex regex = new Regex( pattern );
Match match = regex.Match(sourceValue);
if( match.Success )
{
int feet = 0;
int.TryParse(match.Groups[2].Value, out feet);
int inch = 0;
int.TryParse(match.Groups[4].Value, out inch);
double fracturalInch = 0.0;
if (match.Groups[5].Value.Length == 3)
fracturalInch = (double)(match.Groups[5].Value[0] - '0') / (double)(match.Groups[5].Value[2] - '0');
resultValue = (feet * 12) + inch + fracturalInch;
Perhaps check out the units library? There doesn't seem to be a PHP binding for it, though.
The regexp would look something like this:
"([0-9]+)'\s*([0-9]+)\""
(where \s represents whitespace - I'm not sure how it works in php). Then you extract the first + second group and do
(int(grp1)*12+int(grp2))*2.54
to convert to centimeters.
来源:https://stackoverflow.com/questions/325116/how-to-convert-imperial-units-of-length-into-metric