Как перевести имперские единицы длины в метрику? - PullRequest
3 голосов
/ 28 ноября 2008

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

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

или как это:

$length = "1/2\"";

или фактически любым другим способом, которым мы обычно пишем это.

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

Ответы [ 5 ]

4 голосов
/ 28 ноября 2008

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

$unit = new Zend_Measure_Length($length,Zend_Measure_Length::YARD);
$unit -> convertTo(Zend_Measure_Length::METER);
3 голосов
/ 28 ноября 2008

Вот мое решение. Он использует 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 м.

2 голосов
/ 21 июля 2010

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

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;
1 голос
/ 28 ноября 2008

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

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

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

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

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

1 голос
/ 28 ноября 2008

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

...