通过替换第三个最后位置上的点来转换货币数字与preg_replace

时间:2017-07-18 21:37:02

标签: php regex preg-replace

我试图转换以下数字,以便如果在倒数第三个位置没有使用逗号或点,则所有值都为5460,如果有逗号或点,则为5460,00。 / p>

以下是我的测试编号:

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";

所以我不知道如何检查最后两位数字之前是否有点,如果是,则用逗号替换它。但仅限于最后两位数字。

由于

2 个答案:

答案 0 :(得分: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剩余的短划线将被翻译成逗号和逗号或点,以便同时清空字符串。

答案 1 :(得分: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";

这将自动获取输入的任何值并将其转换为德语等效值。请记住,您还要删除欧元符号!

希望这有帮助! :)