2017-07-18 81 views
0

我试图转换下列数字,以便所有具有相同的值5460(如果在第三个最后位置或5460处没有逗号或点) ,如果有逗号或点,则为00。使用preg_replace将货币数字换成第三个最后位置的点数

这里是我的测试号:

5460 
5.460 
5.460€ 
5460,00 
5460,00€ 
5460.00 
5460.00€ 
5.460,00 
5.460,00€ 
5,460.00 
5,460.00€ 

我用了preg_replace以下的正则表达式:

preg_replace('/[^0-9\,\-]+/','',$number); 

的结果如下

5460 -> 5460 
5.460 -> 5460 
5.460€ -> 5460 
5460,00 -> 5460,00 
5460,00€ -> 5460,00 
5460.00 -> 546000 // wrong 
5460.00€ -> 546000 // wrong 
5.460,00 -> 5460,00 
5.460,00€ -> 5460,00 

我不知道如何优化正则表达式,这样错误的值也会被正确地替换为:

5460.00 -> 546000 // wrong because should be 5460,00 
5460.00€ -> 546000 // wrong because should be 5460,00 

测试用例:

$numbers = array('5460', '5.460', '5.460€', '5460,00', '5460,00€', '5460.00', '5460.00€', '5.460,00', '5.460,00€'); 
foreach ($numbers as $number) 
    echo $number." -> ".preg_replace('/[^0-9\,\-]+/','',$number) . "\n"; 

所以我不知道如何检查,如果最后两个数字前有一个点,如果是用逗号来取代它。但只限于最后两位数字。

感谢

+0

但是...... 5460.00!= 546000!= 5460,00 – Daniel

+2

我必须同意丹尼尔的困惑。你为什么试图将'5460.00'转换为'5460,00'?这个人是否有5千欧元,或54.6万欧元?当然,你希望逗号在*三位数之前出现?像'546,000'一样? –

+0

查看http://ideone.com/Juj0Hd –

回答

1

这做工作,但可能还有一个更简单的解决方案:

$numbers = array('5460', '5.460', '5.460€', '5460,00', '5460,00€', '5460.00', '5460.00€', '5.460,00', '5.460,00€'); 
foreach ($numbers as $k => $number) { 
    $number = preg_replace('~[.,](?=\d{2}\b)|\p{Sc}~u', '#', $number); 
    $number = strtr(rtrim($number, '#'), ['#' => ',', '.' => '', ',' => '']); 
    echo $numbers[$k], ' -> ', $number, PHP_EOL; 
} 

模式的货币符号和点或逗号后面只有两个数字相匹配。他们被替换为破折号。

例如:5.460,00€ => 5.460#00#

然后破折号被剥离在右边,并用剩余的strtr破折号同时转换为逗号和逗号或点到空字符串。

0

考虑有多少不同的方式来写的货币(甚至只是用欧元),你可能很难用一个简单的正则表达式来识别“真”价值人正打算进入。

你可以从像PHP的money_format()获益系统自动校正任何可能的混乱,通过与setlocale()设置地方:

setlocale(LC_MONETARY, 'de_DE'); 

$numbers = array('5460', '5.460', '5.460€', '5460,00', '5460,00€', '5460.00', '5460.00€', '5.460,00', '5.460,00€'); 
foreach ($numbers as $number) 
    echo money_format('%i', $number) . "\n"; 

这会自动带输入的任何值,并将其转换为德国等同。请记住,您还需要去掉欧元符号!

希望这会有所帮助! :)