2012-02-02 35 views
8

我喜欢将价格转换为浮点值的字符串。价格来自不同语言和国家,可以是这样的:价格字符串浮动

1,00 € 
€ 1.00 
1'000,00 EUR 
1 000.00$ 
1,000.00$ 
1.000,00 EURO 

或任何你能想到的...

不知道我得到了全方位的准备与我的例子。我也不确定是否可以盲目地进行国际转换,也许我必须使用语言代码?所以开始欧元和美元就足够了。

floatval()是一种愚蠢的,所以我需要更多的东西在这里。我想我应该先删除数字旁边的所有字符,,.。然后修复,/.并最终使用floatval。

有人做过这件事,可以帮助我一点吗?

我宁愿没有正则表达式的解决方案;)

+0

为什么没有正则表达式?这极大地限制了你... – Nick 2012-02-02 10:18:20

+1

所以输入是可变的,即使点和零可能意味着数千分隔符或小数点..并且你认为这有一个魔术锤,对于你可能从用户那里得到的所有可能的输入? – 2012-02-02 10:18:47

+0

@尼克我说“比较喜欢”,因为我认为正则表达式很难阅读和难以维护。但如果需要的话,我仍然会使用它们。 – PiTheNumber 2012-02-02 10:30:42

回答

12

好吧,我没有尝试过自己。你觉得这怎么样?

function priceToFloat($s) 
{ 
    // convert "," to "." 
    $s = str_replace(',', '.', $s); 

    // remove everything except numbers and dot "." 
    $s = preg_replace("/[^0-9\.]/", "", $s); 

    // remove all seperators from first part and keep the end 
    $s = str_replace('.', '',substr($s, 0, -3)) . substr($s, -3); 

    // return float 
    return (float) $s; 
} 

这里一些测试:http://codepad.org/YtiHqsgz

对不起。我不能包含其他功能,因为键盘不喜欢它们。但我比较他们,并有像“22 000,76”或“22.000”

字符串有问题更新:由于Limitless isa指出,你可能看看在功能money-format功能构建。

+0

似乎它应该做的伎俩。出于好奇,filter_var方法不适合你? – Oldskool 2012-02-02 11:28:24

+0

@Oldskool filter_var解决方案非常好!但它不适用于没有美分的价格。 – PiTheNumber 2012-02-02 11:39:50

+0

您需要添加标志'filter_var($价格,FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);' – 2014-12-22 05:37:52

2

删除所有的非数字字符应该给你分钱的价格。然后,您可以将其除以100以获得“可读性”的价格。您可以使用类似于filter_var FILTER_SANITIZE_NUMBER_INT的方法来做到这一点。例如:

$cents = filter_var($input, FILTER_SANITIZE_NUMBER_INT); 
$price = floatval($cents/100); 

上面是未经测试,但类似的东西可能是你要找的东西。

2

此功能将解决您的问题:

function priceToSQL($price) 
{ 
    $price = preg_replace('/[^0-9\.,]*/i', '', $price); 
    $price = str_replace(',', '.', $price); 

    if(substr($price, -3, 1) == '.') 
    { 
     $price = explode('.', $price); 
     $last = array_pop($price); 
     $price = join($price, '').'.'.$last; 
    } 
    else 
    { 
     $price = str_replace('.', '', $price); 
    } 

    return $price; 
} 
+0

谢谢!这对大多数情况非常好。我仍然发现一些例子,例如“22 000,76”和“22.000”等功能存在问题。我试图构建我的[自己的版本](http://stackoverflow.com/a/9111507/956397)。 – PiTheNumber 2012-02-02 11:44:58

+0

我用你提供的箱子固定了它,它现在完美地工作。 – 2012-02-02 17:53:37

+1

+1现在工作正常。做得好!这个晚上是个好主意,我现在可以用三条线做同样的事情。一探究竟。 – PiTheNumber 2012-02-03 07:06:08

1

要删除所有,但数字,逗号和句号:

<?php 

$prices = array("1,00 €", 
"€ 1.00", 
"1'000,00 EUR", 
"1 000.99$", 
"1,000.01$", 
"1.000,10 EURO"); 

$new_prices = array(); 
foreach ($prices as $price) { 
    $new_prices[] = preg_replace("/[^0-9,\.]/", "", $price); 
} 

print_r($new_prices); 

输出:

Array ([0] => 1,00 [1] => 1.00 [2] => 1000,00 [3] => 1000.99 [4] => 1,000.01 [5] => 1.000,10) 

现在,让我们利用parseFloat功能从Michiel - php.net(我不会粘贴在这里,因为它是一个非常大的功能):

<?php 

$prices = array("1,00 €", 
"€ 1.00", 
"1'000,00 EUR", 
"1 000.99$", 
"1,000.01$", 
"1.000,10 EURO"); 

$new_prices = array(); 
foreach ($prices as $price) { 
    $new_prices[] = parseFloat(preg_replace("/[^0-9,\.]/", "", $price)); 
} 

print_r($new_prices); 

输出将是:

Array ([0] => 1 [1] => 1 [2] => 1000 [3] => 1000.99 [4] => 1000.01 [5] => 1000.1) 
+0

不错,谢谢!我也尝试了Michiel功能,但没有得到它的工作。您的解决方案存在“22 000,76”和“22.000”的问题。所以我试图建立我的[自己的版本](http://stackoverflow.com/a/9111507/956397)。 – PiTheNumber 2012-02-02 11:43:31

+0

上述不应该有任何问题“22 000,76”假设它的意思是“22000.76”而不是“2200076.00”。然而,你的第二个例子不会工作,因为它不是一个浮点数。但是对第三个字符的简单检查可以解决这个问题。 – Nick 2012-02-02 11:55:17

+0

也许我做错了什么事,但parseFloat_Nick()返回做一些奇怪的“0” [我](http://jsbin.com/idozuc)。 – PiTheNumber 2012-02-02 12:44:58

2

价格数量 号码价格例子

<?php 

    $number="1.050,50"; 

    $result=str_replace(',','.',str_replace('.','',$number)); 
    echo $result. "<br/>"; 
    // 1050.50 

    setlocale(LC_MONETARY, 'tr_TR'); 
    echo money_format('%!.2n', $result) ; 
    // 1.050,50 

?> 
+0

我接着说:.UTF-8'到LC_MONETARY,并试图在我的测试字符串,但没有很好地工作:http://codepad.org/s00IFyR5 反正'money_format'被interessting! – PiTheNumber 2015-10-30 09:43:08

0

并不完美,但它的工作

function priceToFloat($s){ 
    // clear witespaces 
    $s = trim($s); 
    $s = str_replace(' ', '', $s); 

    // is it minus value 
    $is_minus = false; 
    if(strpos($s, '(') !== false) 
     $is_minus = true; 
    if(strpos($s, '-') !== false) 
     $is_minus = true; 

    // check case where string has "," and "." 
    $dot = strpos($s, '.'); 
    $semi = strpos($s, ','); 
    if($dot !== false && $semi !== false){ 
     // change fraction sign to #, we change it again later 
     $s = str_replace('#', '', $s); 
     if($dot < $semi) $s = str_replace(',','#', $s); 
     else $s = str_replace('.','#', $s); 

     // remove another ",", "." and change "#" to "." 
     $s = str_replace([',','.', '#'], ['','', '.'], $s); 
    } 
    $s = str_replace(',', '.', $s); 
    // clear usless elements 
    $s = preg_replace("/[^0-9\.]/", "", $s); 

    // if it minus value put the "-" sign 
    if($is_minus) $s = -$s; 
    return (float) $s; 
} 

工作情况

$prices = [ 
    '123.456,789', 
    '123,456.789', 
    '123 456,789', 
    '123 456.789', 
    '-123,456.789', 
    '(123,456.789)', 
]; 
foreach($prices as $price) 
    echo priceToFloat($price).'<br />'; 

回报

123456.789 
123456.789 
123456.789 
123456.789 
-123456.789 
-123456.789