本文最后更新于 1180 天前,其中的信息可能已经有所发展或是发生改变。
问题背景
取一段文本中的所有11位数字,估且可以理解成手机号吧。
具体要求
- 11位数字
- 8位的,超过11位的都不算
问题变更
正则网站测试正常
在一个网站上regex101做好的手机号的识别,大家感兴趣的可以自己去试一试。

数据如下:
12345678901
a12345678901
12345678901bb
a12345678901bb
18274877543aa
python测试失败
import re
re.findall("(?<=[^\d])[12]{2}(?=[^\d])","12abc12")
查找2位数
re.findall("[12]{2}","12abc12")
Out[5]: ['12', '12']
包含3位数失效
re.findall("[12]{2}","12abc123")
Out[6]: ['12', '12']
我们其实只想要特定位数的,这里应该只返回12即可,后面那个123中的12不应该被提取出来。
看正常的正则代码在python里面的表现
import re
mobile = ["12345678901", "a12345678901", "12345678901bb", "a12345678901bb","18274877543aa"]
def regmobile(mobile):
pattern = "(?<=[^\d])1[0-9]{10}(?=[^\d])"
return re.findall(pattern,mobile)
[regmobile(x) for x in mobile]
Out[12]: [[], [], [], ['12345678901'], []]
看到只匹配了第4个,其余的一个都没有命中,但是在我们练习的网站上,是全部匹配成功的。
解决方案
问题原因
- python中的look behind是要有固定的长度的,所以没办法匹配空值的例子,比如mobile中的
12345678901
。
解决办法
reg = re.compile(r"(?:^|(?<=[^\d]))1[0-9]{10}(?=[^0-9]|$)")
结合^
和$
这两个符号可以解决零宽断言的问题。
解释一下re.compile什么意思
就是把正则的语句提前编译一下,再查找起来会快很多。相当于对re又起了一个实例。
用法如下:reg.findall(mobile)
相似问题
如何提取只有4-6位的数字验证码?
这个问题有效整理成,如何利用tasker自动转发短信验证码?
- 通过m1电脑,可以直接通过bark在熄屏时自动推送到PC端。(大大提升PC端使用验证码找手机的用户体验哈)
- 多台手机的验证码转发。准确识别出验证码可以解决出很多问题。
- 自动充值的礼品卡密钥,收到好自动复制到剪贴板,然后并自动打开要充值的APP。