preg_match 默认只匹配单个数字因未用量词,需用 \d+ 提取完整整数;负数用 -?\d+ 并加边界控制;小数需 -?\d+(?:.\d+)?;全角数字需预处理,中文数字需映射转换。

preg_match 提取第一个数字时为什么只拿到个位数
默认的 preg_match 模式没加量词,匹配到一个数字就停了,比如 "abc123def" 里只返回 1。要拿完整整数,得用 + 或 \d+ 明确表示“连续多个数字”。
- 错误写法:
preg_match('/\d/', $str, $m)→ 只捕获首字符 - 正确写法:
preg_match('/\d+/', $str, $m)→ 捕获首个连续数字串,如123 - 如果字符串开头是负号,要支持负数:用
/-?\d+/,但注意-单独出现会被误判,建议加边界控制,比如/(?
preg_match_all 提取所有数字但结果混着小数和整数
正则 \d+ 无法匹配小数点,所以 "3.14 and 42" 会拆成 3、14、42。想保留小数,得显式包含小数点和可选的小数部分。
- 基础小数支持:
/\-?\d+\.?\d*/,但会错匹配"123."这种孤立小数点 - 更稳妥写法:
/\-?\d+(?:\.\d+)?/,用非捕获组限定小数部分必须有数字 - 注意浮点数可能带科学计数法(如
1e5),PHP 原生正则不处理这个,需额外逻辑或改用filter_var($s, FILTER_SANITIZE_NUMBER_FLOAT)预处理
filter_var + FILTER_SANITIZE_NUMBER_INT 不如预期
这个过滤器不是“提取”,而是“清理”:它删掉所有非数字字符,包括负号和小数点,"-12.3abc" 会变成 "123",完全丢失符号和精度。
10分钟内自己学会PHP其中,第1篇为入门篇,主要包括了解PHP、PHP开发环境搭建、PHP开发基础、PHP流程控制语句、函数、字符串操作、正则表达式、PHP数组、PHP与Web页面交互、日期和时间等内容;第2篇为提高篇,主要包括MySQL数据库设计、PHP操作MySQL数据库、Cookie和Session、图形图像处理技术、文件和目录处理技术、面向对象、PDO数据库抽象层、程序调试与错误处理、A
- 仅适合纯整数清洗场景,比如表单输入强制转数字
- 若原始字符串含多个数(如
"score:85, level:9"),它会拼成"859",不可逆 - 替代方案:先
preg_match_all提取候选,再用intval()或floatval()转类型,可控性高得多
中文或全角数字混在字符串里怎么处理
正则 \d 只匹配 ASCII 数字(0–9),对中文数字(一、二、三)或全角数字(012)完全无效。PHP 默认不开启 Unicode 模式,也没内置中文数字转阿拉伯数字逻辑。
立即学习“PHP免费学习笔记(深入)”;
- 简单绕过:用
str_replace先把全角数字换成半角,例如str_replace(['0','1','2'], ['0','1','2'], $str) - 中文数字需查表转换,不能靠正则一步到位;常见做法是预定义映射数组,再用
strtr()批量替换 - 如果只是想“跳过中文、只提 ASCII 数字”,确保正则加
u修饰符(/\d+/u)防止 UTF-8 截断,但依然不识别中文字符本身
"item123count" 里提 123 没问题,但从 "level1234567" 提 1234567 就可能超出整型范围,或者后续参与计算前没校验是否为空数组。正则一跑就以为完事了,其实后面那步 isset($m[0]) ? (int)$m[0] : 0 才真正决定结果稳不稳。










