PHP: unformat money

y a-t-il un moyen d'obtenir la valeur flottante d'une chaîne comme celle-ci: 75,25 € , autre que parsefloat(str_replace(',', '.', $var)) ?

je veux que cela dépende du langage courant du site, et parfois la virgule pourrait être remplacée par un point.

29
demandé sur mskfisher 2011-02-28 11:48:31

8 réponses

vous pouvez utiliser

exemple tiré du manuel:

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

donne: float(75.25)

notez que l'extension intl n'est pas activée par défaut. Veuillez vous référer aux " instructions D'Installation .

41
répondu Gordon 2014-11-08 01:52:40

c'est une solution un peu plus complexe/lente, mais fonctionne avec toutes les locales. Parce que la solution de @rlenom ne fonctionne qu'avec des points comme séparateur décimal, et certaines locales, comme spanish one, utilisent la virgule comme séparateur décimal.

<?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);
    $removedThousendSeparator = preg_replace('/(\.|,)(?=[0-9]{3,}$)/', '',  $stringWithCommaOrDot);

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

Essais:

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

mises en garde: Échoue si la partie décimale ont plus de deux chiffres.

c'est une implémentation de cette bibliothèque: https://github.com/mcuadros/currency-detector

39
répondu mcuadros 2013-11-04 14:12:02

utilisation ereg_replace

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

sorties

1000000

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

mise à jour


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

sorties

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

et si vous le jetez comme un entier

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

sorties

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

Donc voilà. seule ligne, on remplacer. vous êtes bon pour aller.

38
répondu rlemon 2011-09-13 22:28:43

vous allez devoir enlever le symbole de devise de la chaîne. Le intval de PHP s'arrête au premier caractère non numérique qu'il trouve.

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

bien que si vous avez une valeur comme 0.25 , vous pourriez utiliser floatval à la place.

$float = floatval(preg_replace('/[^\d\.]/', '', '0.25')); // 100.25
6
répondu Rocket Hazmat 2011-09-13 20:34:10

PHP a intval ( voici les docs ), qui est (pour autant que je puisse dire) exactement le même que JavaScript parseInt .

Cependant, pour ce qui est de la valeur, Je ne pense pas que l'une ou l'autre fonction vous aidera avec ce que vous essayez de faire. Parce que le premier caractère n'est pas numérique, les deux flippent (PHP vous donnera 0, JS vous donnera NaN ). Donc, dans l'une ou l'autre langue, vous allez devoir faire un parsing string/regex.

2
répondu sdleihssirhc 2011-09-13 20:24:32

Coulée est votre ami:

$int = (int) $string;

mise à Jour basé sur l'op :

Essayez quelque chose comme ceci:

<?php

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

echo extract_numbers('0');

?>

Démo: http://codepad.org/QyrfS7WE

1
répondu Neal 2011-09-13 20:30:38

j'ai eu un problème similaire où je n'ai pas reçu le symbole de devise, juste les chaînes (i.e.: 1.234.567.89 ou 1.234.567, 89).

cela m'a aidé à normaliser les deux cas en flotteurs:

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

mais la réponse de Gordon est beaucoup plus claire.

1
répondu Edson Medina 2012-03-27 18:40:52

je suis un internaute novice, donc il y a probablement un inconvénient évident (pour les autres, pas pour moi) à l'approche ci-dessous, mais j'ai pensé que je le partagerais de toute façon. Je serais intéressé de savoir si c'est plus rapide ou plus lent que d'utiliser preg_replace, mais je n'ai pas fait de test de vitesse.

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

$ dirtyString peut être un tableau, donc:

$badChars = array("$", ",", "(", ")");
$dirtyStrings = array("(,895.23)", "1,067.04", "83.22", "34.48");
$cleanStrings = str_ireplace($badChars, "", $dirtyStrings);

echo var_dump($cleanStrings);
1
répondu user2840024 2013-10-02 19:19:02