开发者

What a quick way to clean up a monetary string [duplicate]

This question already has answers here: Closed 10 years ago.

Possible Duplicate:

PHP: unformat money

How to get rid of everything that is not a number or dot, replacing 开发者_如何转开发, with . using a light regex?

Examples:

$50.45     = 50.45
USD 50.45  = 50.45
50,45      = 50.45
USD$ 50.45 = 50.45


<?php
$money = array(
    '$50.45',
    'USD 50.45',
    '50,45',
    'USD$ 50.45'
);

// remove everything except a digit "0-9", a comma ",", and a dot "."
$money = preg_replace('/[^\d,\.]/', '', $money);

// replace the comma with a dot, in the number format ",12" or ",43"
$money = preg_replace('/,(\d{2})$/', '.$1', $money);

print_r($money);
?>

Output:

Array
(
    [0] => 50.45
    [1] => 50.45
    [2] => 50.45
    [3] => 50.45
)


preg_replace('/.*?(\d+)(?:[.,](\d+))?.*/', '\1.\2', $string);


The solution I came up with that works with your examples was:

preg_replace("([^0-9\.])","",str_replace(",",".",$val));

Assuming comma only ever appears when it should be a decimal point, as opposed to being a thousands separator. It replaces those with a decimal place, and then removes all non numeric/decimal characters from the remaining string altogether.

Test script:

$inputs = array("\$50.45", "USD 50.45", "50,45", "USD\$ 50.45");

foreach ($inputs as $val) {
    $cleanVal = preg_replace("([^0-9\.])","",str_replace(",",".",$val));
    echo "GIVEN: <b>".$val."</b> -> CLEAN: <b>".$cleanVal."</b><br/>";    
}

Output:

GIVEN: $50.45 -> CLEAN: 50.45

GIVEN: USD 50.45 -> CLEAN: 50.45

GIVEN: 50,45 -> CLEAN: 50.45

GIVEN: USD$ 50.45 -> CLEAN: 50.45


This would work too for the given examples (demo):

$money = array(
    '$50.45',
    'USD 50.45',
    '50,45',
    'USD$ 50.45'
);

foreach ($money as $val) {
    echo filter_var(
        str_replace(',', '.', $val),
        FILTER_SANITIZE_NUMBER_FLOAT,
        FILTER_FLAG_ALLOW_FRACTION
    ), PHP_EOL;
}

// gives 
// 50.45
// 50.45
// 50.45
// 50.45

This will fail when the string contains fractions and thousand separators. There is a filter flag FILTER_FLAG_ALLOW_THOUSAND that could potentially handle thousand separators as well. But since the thousand separators can indicate fraction in other locales and you want to take it into account, it wont work in your scenario.

For a more powerful parsing alternative try

  • numfmt_parse_currency - Parse a string into a double and a currency using the NumberFormatter.

A simple example can be found in PHP: unformat money. The example code in the accepted answer will only parse $50.45 though. The NumberFormatter can be configured with additional rules, so while I am not 100% certain, I think it should be possible with it.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜