Как преобразовать императивные единицы длины в метрику?

Здесь я столкнулся с проблемой, которая, как я считаю (или, по крайней мере, надежда), была решена уже 1 миллион раз. То, что я получил в качестве ввода, – это строка, представляющая длину объекта в имперских единицах. Это может выглядеть так:

$length = "3' 2 1/2\""; 

или вот так:

 $length = "1/2\""; 

или на самом деле каким-либо другим способом мы обычно его будем писать.

Стремясь уменьшить глобальное изобретение на колесиках, я задаюсь вопросом, есть ли какая-то функция, класс или регулярное выражение, что позволит мне преобразовать длину Имперского в длину Метрики?

Вот мое решение. Он использует eval () для оценки выражения, но не беспокойтесь, проверка регулярного выражения в конце делает его полностью безопасным.

 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; } } 

Так, например, строка

 3' 2 1/2" 

преобразуется в выражение

 3*12+2+1/2 

который оценивается

 38.5 

который, наконец, преобразуется в 0.9779 метров.

Для этой цели Zend Framework имеет измерительный компонент. Я предлагаю вам проверить это – здесь .

 $unit = new Zend_Measure_Length($length,Zend_Measure_Length::YARD); $unit -> convertTo(Zend_Measure_Length::METER); 

Имперские значения строк немного сложнее, поэтому я использовал следующее выражение:

 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; 

Возможно, проверьте библиотеку единиц ? Тем не менее, похоже, для него не существует привязки к PHP.

Регулярное выражение будет выглядеть примерно так:

 "([0-9]+)'\s*([0-9]+)\"" 

(где \ s представляет пробелы – я не уверен, как это работает в php). Затем вы извлекаете первую + вторую группу и делаете

 (int(grp1)*12+int(grp2))*2.54 

для преобразования в сантиметры.