我正在开发一个将数据传递到在线会计网站的模块,为了正确解析,我需要做的一件事是从产品价格中删除货币符号。
我的正则表达式如下:
$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英镑。所以,当我把它投射到一个浮点数时它什么也没有返回。
这个正则表达式我在哪里错了?
答案 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));