6

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
Community
  • 1
  • 1
CodeOverload
  • 47,274
  • 54
  • 131
  • 219

4 Answers4

6
<?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
)
Shef
  • 44,808
  • 15
  • 79
  • 90
1
preg_replace('/.*?(\d+)(?:[.,](\d+))?.*/', '\1.\2', $string);
Artefacto
  • 96,375
  • 17
  • 202
  • 225
1

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

Community
  • 1
  • 1
Codecraft
  • 8,291
  • 4
  • 28
  • 45
0

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

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.

Community
  • 1
  • 1
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • thousand separator support is really needed in any web-based solution, I voted you down sorry. – malhal Dec 15 '15 at 22:03
  • @malhal Yes, I explicitly state that the code snippet won't work with a thousand separator. And I offer two possible workarounds. Have you tried those? – Gordon Dec 16 '15 at 11:08