Konvertieren einer Zahl mit Komma als Dezimalpunkt in Gleitkomma

70

Ich habe eine Preisliste mit einem Komma für einen Dezimalpunkt und einem Punkt als Tausendertrennzeichen.

Einige Beispiele:

12,30
116,10
1,563,14

Diese kommen in diesem Format von Dritten. Ich möchte sie in Floats umwandeln und zusammenfügen.

Was ist der beste Weg, dies zu tun? number_format scheint mit diesem Format nicht zu funktionieren, und str_replace scheint übertrieben zu sein, da ich es mehr als einmal für jede Nummer tun muss.

Gibt es einen besseren Weg? Vielen Dank.

Aine
quelle
Sie könnten die Punkte herausdrücken, dann das Komma gegen den Punkt tauschen und als Float analysieren. Das sind nur 2 Ersetzungen. Das ist nicht schrecklich, es sei denn, Sie machen Zehntausende von Aufnahmen auf einmal
DampeS8N

Antworten:

117

Das str_replace()Entfernen der Punkte ist nicht übertrieben.

$string_number = '1.512.523,55';
// NOTE: You don't really have to use floatval() here, it's just to prove that it's a legitimate float value.
$number = floatval(str_replace(',', '.', str_replace('.', '', $string_number)));

// At this point, $number is a "natural" float.
print $number;

Dies ist mit ziemlicher Sicherheit die am wenigsten CPU-intensive Art und Weise, wie Sie dies tun können, und es besteht die Wahrscheinlichkeit, dass dies unter der Haube geschieht, selbst wenn Sie eine ausgefallene Funktion verwenden.

Teekin
quelle
3
oder einfach$number = str_replace( [',','.'], ['.'], $string_number )*1.0;
Jeff
3
@ Jeff, es ist richtig zu versuchen, so wenig Codezeilen wie möglich zu schreiben, aber ich denke, dass die Lesbarkeit von Code ein Muss bei der Entwicklung ist, noch wichtiger als weniger zu schreiben.
Manuman94
1
hmm, ja, ich habe anscheinend die "Ersatzbestell-Gotcha" übersehen, die bei Verwendung von MySQL nicht auftritt replace. Die richtige Zeile lautet also$number = str_replace( ['.',','], ['','.'], $string_number )*1.0;
Jeff,
3
@ manuman94, ich glaube nicht, dass das Eliminieren eines unnötigen Funktionsaufrufs die Lesbarkeit verringert.
Jeff
1
@ Jeff ich mache haha ​​aber das ist natürlich meine meinung. Ich schätze Ihre Bemühungen, der Gemeinschaft zu helfen, es war nur mein Standpunkt. Schöne Grüße!
Manuman94
26

Diese Funktion ist kompatibel für Zahlen mit Punkten oder Kommas als Dezimalstellen

function floatvalue($val){
            $val = str_replace(",",".",$val);
            $val = preg_replace('/\.(?=.*\.)/', '', $val);
            return floatval($val);
}

Dies funktioniert für alle Arten von Eingaben (amerikanischer oder europäischer Stil)

echo floatvalue('1.325.125,54'); // The output is 1325125.54
echo floatvalue('1,325,125.54'); // The output is 1325125.54
echo floatvalue('59,95');        // The output is 59.95
echo floatvalue('12.000,30');    // The output is 12000.30
echo floatvalue('12,000.30');    // The output is 12000.30
Ramon
quelle
Das ist Genie!
Adam
21

Wenn Sie PHP5.3 oder höher verwenden, können Sie numfmt_parse verwenden , um "ein umgekehrtes Zahlenformat" auszuführen. Wenn nicht, haben Sie die Vorkommen nicht durch preg_replace / str_replace ersetzt.

Björn
quelle
1
Sie benötigen auch PECL intl> = 1.0.0
riotera
2
"Sie benötigen auch PECL intl> = 1.0.0" Nein, es heißt, Sie benötigen entweder PHP 5.3> oder Sie müssen es über das PECL intl-Paket 1.0.0 installieren. PHP 5.3+ hat die Unterstützung eingebaut.
Michael Ryan Soileau
1
Sie müssen in der Tat überprüfen, ob die intlErweiterung aktiviert ist. Es ist nicht eingebaut, es muss entweder explizit kompiliert oder als separate Erweiterung installiert werden. Nicht alle Hosting-Anbieter installieren es mit PHP.
Cronfy
12

Sie können die NumberFormatter- Klasse mit ihrer parseMethode verwenden .

Gumbo
quelle
4
Nur in 5.3 oder höher verfügbar, nur als Haftungsausschluss. ;-)
Björn
... und nur mit der intlErweiterung kompiliert.
Ian Dunn
7

Angenommen, sie befinden sich in einer Datei oder einem Array, ersetzen Sie sie einfach als Stapel (dh auf einmal):

$input = str_replace(array('.', ','), array('', '.'), $input); 

und dann verarbeiten Sie die Zahlen von dort aus, wobei Sie die lose typisierte Natur von PHP voll ausnutzen.

Paul Norman
quelle
Ich würde auch den Typ float wie folgt umwandeln: $ v = (float) str_replace (['.', ','], ['', '.'], $ V);
Francisco Luz
6

Könnte übertrieben aussehen, konvertiert jedoch jedes Format, unabhängig vom Gebietsschema:

function normalizeDecimal($val, int $precision = 4): string
{
    $input = str_replace(' ', '', $val);
    $number = str_replace(',', '.', $input);
    if (strpos($number, '.')) {
        $groups = explode('.', str_replace(',', '.', $number));
        $lastGroup = array_pop($groups);
        $number = implode('', $groups) . '.' . $lastGroup;
    }
    return bcadd($number, 0, $precision);
}

Ausgabe:

.12           -> 0.1200
123           -> 123.0000
123.91        -> 12345678.9100
123 456 78.91 -> 12345678.9100
123,456,78.91 -> 12345678.9100
123.456.78,91 -> 12345678.9100
123 456 78,91 -> 12345678.9100
Adrian Piechota
quelle
1

aus dem PHP-Handbuch:

str_replace - Ersetzen Sie alle Vorkommen der Suchzeichenfolge durch die Ersatzzeichenfolge

Ich würde diesen Weg gehen und dann von String zu Float - Floatval konvertieren

Yishai Landau
quelle