web-dev-qa-db-fra.com

Déformez l'argent lors de l'analyse de PHP

Existe-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 de la langue actuelle du site, et parfois la virgule pourrait être remplacée par un point.

34
cili

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 extension intl n'est pas activé par défaut. Veuillez vous référer aux Instructions d'installation .

43
Gordon

C'est une solution un peu plus complexe/lente, mais fonctionne avec tous les paramètres régionaux. Parce que la solution de @ rlenom ne fonctionne qu'avec des points comme séparateur décimal et que certains paramètres régionaux, comme l'espagnol, 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);
}

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]

Avertissements: échoue si la partie décimale comporte plus de deux chiffres.

Il s'agit d'une implémentation de cette bibliothèque: https://github.com/mcuadros/currency-detector

45
mcuadros

utilisez ereg_replace

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

les sorties

1000000

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

Mise à jour


<?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);
}
?>

Sorties

$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

et si vous le transformez en entier

<?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);
}
?>

sorties

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

Alors voilà. une seule ligne, une remplacer. vous êtes prêt à partir.

42
rlemon

Vous devrez supprimer le symbole monétaire de la chaîne. intval de PHP s'arrête au premier caractère non numérique qu'il trouve.

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

Mais si vous avez une valeur comme $100.25, vous voudrez peut-être utiliser floatval à la place.

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

PHP a intval ( voici les documents ), ce qui est (pour autant que je sache) exactement le même que parseInt de JavaScript.

Cependant, pour ce qui en vaut la peine, je ne pense pas que l'une ou l'autre fonction vous aidera dans ce que vous essayez de faire. Parce que le premier caractère n'est pas numérique, les deux paniquent (PHP vous donnera 0, JS vous donnera NaN). Donc, dans les deux langues, vous devrez faire une analyse de chaîne/expression régulière.

2
sdleihssirhc

Le casting est votre ami:

$int = (int) $string;

Mise à jour  basé sur op:

Essayez quelque chose comme ceci:

<?php

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

echo extract_numbers('$100');

?>

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

1
Neal

Je suis un débutant, il y a donc probablement un inconvénient évident (pour d'autres, pas pour moi) à l'approche ci-dessous, mais j'ai pensé que je la 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 fait aucun test de vitesse.

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

$ dirtyString peut être un tableau, donc:

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

echo var_dump($cleanStrings);
1
user2840024

J'ai eu un problème similaire où je n'ai pas reçu le symbole monétaire, juste les chaînes (c'est-à-dire: 1 234 567,89 ou 1 234 567,89).

Cela m'a aidé à normaliser les deux cas en flottants:

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

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

1
Edson Medina