解析数字但保持负数

时间:2013-11-13 21:27:37

标签: php regex numbers

我正在尝试将数字格式化为其原始形式,但请确定它是否为负数。堆栈溢出的人让我看到了这个非常好用的代码,但它没有保留负面信息。

有人能帮助我更好地解决这个问题吗?

编辑 - 对于美元货币/正常数字

示例:

  

1,234 = 1234

     

-1,234 = -1234

     

1,234.00 = 1234

     

1,234.56 = 1234.56

function numberUnformat($number)
{
   $cleanString = preg_replace('/([^0-9\.,])/i', '', $number);
   $onlyNumbersString = preg_replace('/([^0-9])/i', '', $number);

   $separatorsCountToBeErased = strlen($cleanString) - strlen($onlyNumbersString) - 1;

   $stringWithCommaOrDot = preg_replace('/([,\.])/', '', $cleanString, $separatorsCountToBeErased);
   $removedThousendSeparator = preg_replace('/(\.|,)(?=[0-9]{3,}$)/', '', $stringWithCommaOrDot);

   return (float) str_replace(',', '.', $removedThousendSeparator);
}

6 个答案:

答案 0 :(得分:6)

如果你有可用的ICU扩展(在PHP 5.3中捆绑),请尝试:

$formatter = new NumberFormatter('en_US', NumberFormatter::DECIMAL);
echo $formatter->parse('-1,234.56');

答案 1 :(得分:2)

更改正则表达式以匹配负数:

$cleanString = preg_replace('/([^\-0-9\.,])/i', '', $number);

测试用例:

echo numberUnformat('1,234')."\n";
echo numberUnformat('-1,234')."\n";
echo numberUnformat('1,234.00')."\n";
echo numberUnformat('1,234.56 ')."\n";

输出:

1234
-1234
1234
1234.56

Demo!

答案 2 :(得分:2)

如果你想删除字符串中间的任何无关的减号:

$cleanString = preg_replace('/[^0-9.,-]|(?<=.)-/', '', $number);
$onlyNumbersString = preg_replace('/[^0-9-]|(?<=.)-/', '', $number);

请注意,您原件中不需要括号,反斜杠或/i

答案 3 :(得分:2)

我实际上会在函数中添加一些参数以允许指定分组和小数分隔符(并且可能允许转换为float或decimal的能力,并转到这样的解决方案:

function number_unformat($num_string, $group_sep = ',', $dec_sep = '.', $cast_to_type = true) {
    if (substr_count($num_string, $dec_sep) > 1) {
        // input was invalid
        throw new Exception('Inavlid string: `' . $num_string . '` passed to function. Too many decimal separators.');
    }   
    // remove grouping separator
    $string = str_replace($group_sep, '', $num_string);
    if (true === $cast_to_type) {
        // change any decimal separators to periods before casting
        $string = str_replace($dec_sep, '.', $string, $count);
        if ($count === 1) {
            return (float)$string;
        } else {
            return (int)$string;
        }
    } else {
        return $string;
    }
}

请注意,这里根本不需要使用正则表达式。

答案 4 :(得分:0)

一个相当快速(虽然不完美)的修复方法是更改​​函数的前两行:

$cleanString = preg_replace('/([^-0-9\.,])/i', '', $number);
$onlyNumbersString = preg_replace('/([^-0-9])/i', '', $number);

如果您有2-434.43这样的数字,这会导致问题。

答案 5 :(得分:0)

人们可能会使用正则表达式来保持负面效果,但对我来说,最后执行以下操作会更简单:

$absvalue = (float) str_replace(',', '.', $removedThousendSeparator);
if ($number[0] == '-') {
    $absvalue = $absvalue * -1.0;
}
return $absvalue;

我可能有一个语法错误,我的PHP生锈了,但想法只是检查输入字符串是否以负号开头,如果是,则将结果乘以负数。