PHP 8.2中正则表达式/£?.*£?/为何无法匹配字符串'£45.56–34.90'?
问题分析与解决
问题场景
在Mac Sonoma 14.5 + PHP 8.2.11环境下,执行以下代码:
$cost = '£45.56–34.90'; $matches = array(); $found = preg_match( '/£?.*£?/', $cost, $matches );
预期preg_match()返回1且$matches包含整个字符串,但实际$found === 0,$matches为空。在regex101上测试正则符合预期,给字符串添加第二个£(£45.56–£34.90)则匹配成功,给正则加g修饰符则$found === false。
原因与解决
1. 加g修饰符返回false的原因
PHP的preg_match()不支持全局匹配修饰符g,该修饰符仅适用于preg_match_all()。使用g会导致preg_match()参数非法,直接返回false。
2. 原正则匹配失败的核心原因
你的字符串包含Unicode字符(£符号、EN DASH破折号),而PHP的preg系列函数默认采用字节匹配模式,未启用UTF-8支持。regex101默认启用了UTF-8模式(u修饰符),所以能正确匹配;而你的正则缺少该修饰符,导致Unicode字符的匹配出现异常。
3. 修复方案
给正则添加u修饰符,启用UTF-8匹配模式:
$found = preg_match( '/£?.*£?/u', $cost, $matches );
此时preg_match()会正确识别字符串中的Unicode字符,返回1且$matches[0]为£45.56–34.90。
4. 优化建议
原正则£?.*£?可以匹配空字符串(比如空输入),如果你的目标是匹配带英镑符号的价格范围,建议使用更精确的正则,避免无效匹配:
// 匹配单个£开头的价格范围 $found = preg_match( '/£\d+\.\d+–\d+\.\d+/u', $cost, $matches );
内容的提问来源于stack exchange,提问作者pandammonium
相关产品推荐
相关产品推荐

