Python从pandas列提取全量数字:解决str.extract正则匹配遗漏问题
问题根因
你之前用的正则和方法存在两个核心错误,导致匹配不全:
- 正则
([?:\s\d+]+)写法逻辑错误:方括号[]是单字符匹配集合,写在里面的?:不会生效为非捕获组标记,只会被识别为要匹配问号、冒号两个普通字符;集合内的\d+也会被拆分为匹配数字、加号两个单字符,整个正则的实际逻辑是连续抓取所有空白、数字、问号、冒号、加号字符,碰到第一个不在这个集合里的字符(也就是示例中86529后面的字母P)就会停止匹配,自然抓不到后面的91897。 - pandas的
.str.extract()方法默认仅返回第一个匹配到的分组结果,就算正则逻辑正确,不用全局匹配方法也无法拿到字符串里所有符合要求的数字。
正确实现代码
要实现「无论数字前后存在字母、空格或特殊字符,提取所有数字实例」的需求,直接用.str.findall()匹配连续数字序列即可,不需要额外写多余的匹配规则:
import pandas as pd # 测试用例 s = pd.Series(['86531 86530 86529PIP 91897PIP']) # 提取所有数字,返回结果为每个元素对应数字列表 num_list = s.str.findall(r'\d+')
上述代码对测试行的返回结果为['86531', '86530', '86529', '91897'],覆盖了所有出现的数字。
如果需要把提取后的数字用空格拼接为单字符串,追加一步join操作即可:
num_str = s.str.findall(r'\d+').str.join(' ')
此时测试行的返回结果为86531 86530 86529 91897。
逻辑说明
- 正则
\d+的规则是匹配任意连续1位及以上的数字,完全不需要额外匹配数字前后的其他字符,天然适配「不管前后是什么内容,只抓数字」的需求 .str.findall()会全局扫描整个字符串,返回所有符合匹配规则的结果,不会碰到第一个非匹配字符就终止匹配。
内容的提问来源于stack exchange,提问作者Hector Rojo
相关产品推荐
相关产品推荐

