开发者

Unformat money when parsing in PHP

开发者 https://www.devze.com 2023-04-04 20:34 出处:网络
Is the开发者_JS百科re a way to get the float value of a string like this: 75,25 €, other than parsefloat(str_replace(\',\', \'.\', $var))?

Is the开发者_JS百科re a way to get the float value of a string like this: 75,25 €, other than parsefloat(str_replace(',', '.', $var))?

I want this to be dependent on the current site language, and sometimes the comma could be replaced by dot.


This is a bit more complex/ slow solution, but works with all locales. @rlenom's solution work only with dots as decimal separator, and some locales, like Spanish, use the comma as decimal separator.

<?php

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

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

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

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

Tests:

['1,10 USD', 1.10],
['1 000 000.00', 1000000.0],
['$1 000 000.21', 1000000.21],
['£1.10', 1.10],
['$123 456 789', 123456789.0],
['$123,456,789.12', 123456789.12],
['$123 456 789,12', 123456789.12],
['1.10', 1.1],
[',,,,.10', .1],
['1.000', 1000.0],
['1,000', 1000.0]

Caveats: Fails if the decimal part have more than two digits.

This is an implementation from this library: https://github.com/mcuadros/currency-detector


use ereg_replace

$string = "$100,000";
$int = ereg_replace("[^0-9]", "", $string); 
echo $int;

outputs

1000000

function toInt($str)
{
    return (int)preg_replace("/\..+$/i", "", preg_replace("/[^0-9\.]/i", "", $str));
}

Update


<?php
$string = array("$1,000,000.00","$1 000 000.00","1,000 000.00","$123","$123 456 789","0.15¢");
foreach($string as $s) {
    echo $s . " = " . toInt($s) . "\n"; 
}
function toInt($str)
{
    return preg_replace("/([^0-9\\.])/i", "", $str);
}
?>

Outputs

$1,000,000.00 = 1000000.00
$1 000 000.00 = 1000000.00
1,000 000.00 = 1000000.00
$123 = 123
$123 456 789 = 123456789
0.15¢ = 0.15

and if you cast it as an integer

<?php
$string = array("$1,000,000.00","$1 000 000.00","1,000 000.00","$123","$123 456 789","0.15¢");
foreach($string as $s) {
    echo $s . " = " . _toInt($s) . "\n";    
}
function _toInt($str)
{
    return (int)preg_replace("/([^0-9\\.])/i", "", $str);
}
?>

outputs

$1,000,000.00 = 1000000
$1 000 000.00 = 1000000
1,000 000.00 = 1000000
$123 = 123
$123 456 789 = 123456789
0.15¢ = 0

So there you have it. single line, one replace. you're good to go.


You can use

  • NumberFormatter::parseCurrency - Parse a currency number

Example from Manual:

$formatter = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
var_dump($formatter->parseCurrency("75,25 €", $curr));

gives: float(75.25)

Note that the intl extension is not enabled by default. Please refer to the Installation Instructions.


You're gonna need to remove the currency symbol from the string. PHP's intval stops at the 1st non-numeric character it finds.

$int = intval(preg_replace('/[^\d\.]/', '', '$100')); // 100

Though if you have a value like $100.25, you might wanna use floatval instead.

$float = floatval(preg_replace('/[^\d\.]/', '', '$100.25')); // 100.25


PHP has intval (here are the docs), which is (as far as I can tell) exactly the same as JavaScript's parseInt.

However, for what's worth, I don't think either function will help you with what you're trying to do. Because the first character is non-numeric, both freak out (PHP will give you 0, JS will give you NaN). So in either language, you're going to have to do some string/regex parsing.


I'm an newbie, so there's probably an obvious (to others, not me) downside to the approach below, but thought I would share it anyway. I'd be interested to know whether it's faster or slower than using preg_replace, but didn't do any speed testing.

$badChars = array("$", ",", "(", ")");
$dirtyString = "($3,895.23)";
$cleanString = str_ireplace($badChars, "", $dirtyString);
echo "$dirtyString becomes $cleanString<p>";

$dirtyString can be an array, so:

$badChars = array("$", ",", "(", ")");
$dirtyStrings = array("($3,895.23)", "1,067.04", "$5683.22", "$9834.48");
$cleanStrings = str_ireplace($badChars, "", $dirtyStrings);

echo var_dump($cleanStrings);


Casting is your friend:

$int = (int) $string;

Update based on op:

Try something like this:

<?php

function extract_numbers($string)
{
    return preg_replace("/[^0-9]/", '', $string);
}

echo extract_numbers('$100');

?>

Demo: http://codepad.org/QyrfS7WE


I had a similar problem where I didn't receive the currency symbol, just the strings (ie: 1,234,567.89 or 1.234.567,89).

This helped me normalize both cases into floats:

$val = str_replace(",", ".", $formatted);
$val = preg_replace("/[\,\.](\d{3})/", "$1", $val);

But Gordon's answer is much cleaner.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号