5

我正在尝试将数字取消格式化为原始形式,但保留它是否为负数。堆栈溢出中的某个人让我找到了这段代码,它工作得非常好,但它并没有保持负面。

谁能帮我更好地解决这个问题?

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

例子:

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

6 回答 6

6

如果您有可用的 ICU 扩展(捆绑在 PHP 5.3 中),请尝试以下操作:

$formatter = new NumberFormatter('en_US', NumberFormatter::DECIMAL);
echo $formatter->parse('-1,234.56');
于 2013-11-13T21:47:33.843 回答
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

演示!

于 2013-11-13T21:34:58.660 回答
2

我实际上会在函数中添加一些参数,以允许指定分组和小数分隔符(并且可能允许转换为浮点数或小数点,并得到如下解决方案:

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

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

于 2013-11-13T21:55:28.460 回答
2

如果您还想删除字符串中间的任何多余的减号:

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

请注意,您不需要括号、反斜杠或/i原始文件。

于 2013-11-13T21:41:59.337 回答
0

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

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

虽然如果你有一个像 2-434.43 这样的数字,这会导致问题。

于 2013-11-13T21:31:59.070 回答
0

人们可以使用正则表达式来保持否定,但对我来说,最后执行以下操作更简单:

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

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

于 2013-11-13T21:34:21.307 回答