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.
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 .
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
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.
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
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.
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');
?>
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.
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);