正则表达式问题 - 删除货币符号

时间:2017-03-20 17:08:12

标签: regex preg-replace

我正在开发一个将数据传递到在线会计网站的模块,为了正确解析,我需要做的一件事是从产品价格中删除货币符号。

我的正则表达式如下:

$regex = '/^\D?([\d\.,]*)\D?$/is';

我已经在https://regex101.com/网站上对此进行了测试,但它运行正常,但当我执行preg_replace时如下:

$price_no_curr = preg_replace($regex,"$1",$product_price);

$product_price,例如£123.45,$price_no_curr只返回原来的123.45英镑。所以,当我把它投射到一个浮点数时它什么也没有返回。

这个正则表达式我在哪里错了?

2 个答案:

答案 0 :(得分:1)

最简单的解决方案,使用/u修饰符使其支持UTF-8字符。

$regex = '/^[^\d\.,]?([\d\.,]*)[^\d\.,]?$/u';
$price_no_curr = preg_replace($regex,"$1",$product_price);

答案 1 :(得分:0)

£超出ASCII范围,需要以UTF-8编码几个字节:

$a="£";
echo implode(' ', array_map(function ($i) {
    return dechex(ord($i));
}, str_split($a)));
// c2 a3

默认情况下,正则表达式引擎逐字节工作(一个字节=一个字符)。这就是\D无法与£的两个字节匹配的原因。

要使其适用于多字节字符串,您需要打开u修饰符。这样,正则表达式引擎将逐个字符地读取字符串,无论用于编码它的字节数是多少。 您的模式可以这样写:

$regex = '/^\D?([\d.,]*)\D?$/u';

但如果更改量词,也可以在没有u修饰符的情况下执行此操作:

$regex = '/^\D*([\d.,]*)\D*$/';

更简单灵活的方法是删除所有货币并最终删除空格而不考虑其位置:

$str = preg_replace('~[\p{Sc}\s]+~u', '', $str);

\p{Sc}是一个包含所有货币符号的unicode字符类。

或更根本地:

$str = preg_replace('~[^\d.,]+~u', '', $str);

或没有正则表达式:

$str = '£1823.45';
$allowed_chars = [0,1,2,3,4,5,6,7,8,9,'.',','];
echo implode('', array_intersect(str_split($str), $allowed_chars));