分享一个我维护了几年的匹配国内手机号码的正则表达式列表

2019-01-07 14:16:17 +08:00
 vincentxue



项目地址是: https://github.com/VincentSit/ChinaMobilePhoneNumberRegex

列了一些常用的情况,例如匹配所有号码、所有支持短信功能的号码,包括手机卡、数据卡( IoT )和上网卡以及细分运营商匹配等。

初衷是由于国家一直在放出和使用新的号段,有些使用新的号段的用户无法通过手机号码的正则验证,网上很多正则并不能及时地更新,去找了下开源的项目也没人做这个事,我就自己写了一个。

最近更新支持了最新的号段,做了有限的测试,发到这里一是考虑自身水平有限,请各位大佬提提建议,找找 bug,二是广而告之,希望能帮助到有需要的同学。

关于测试方面,我的设想是想给每个常用语言做一个开源库包含这些正则,该语言相关的测试会在库源码里做。这样使用起来就可以直接引用库封装好的代码,更省事一些。但是我实现了一个语言后发现这是个大坑,得慢慢填。

需要说明的是因为考虑到方便使用的原因,有些正则其实并不是传统意义上极致优化的,可以根据自身需要去修改。例如不需要匹配国家码,可以去掉匹配国家码的那一段。但除非匹配量非常巨大,否则这个性能差别是可以忽略的。我在我机器上用 PHP 7 测了一下匹配一百多万行的手机号码,性能差距还是能接受的。
7702 次点击
所在节点    分享创造
61 条回复
Paff
2019-01-07 17:14:04 +08:00
star 了,好东西
phpcxy
2019-01-07 17:20:50 +08:00
我都是 1 开头的 11 位数字
vincentxue
2019-01-07 17:21:46 +08:00
哇谢谢大家哈,好多人点 Star,谢谢,但是记得 Watch 一下才能及时得到更新啊。


@Lax 谢谢提醒,我稍后确认一下资料就加上。

@lion9527 嗯可能验证码可以不用那么严格,但是各家有各家的需求,有些可能专门匹配手机号码,可能就要求精确一些。

@usapla 啥啥啥?

@GuryYu 就是正则链接到的那个网站啊。https://www.debuggex.com/ ,输入正则就会显示了,然后需要分享点上方的 Share 就可以。

@fmumu 这个又得挖坑了,我先把各语言的库填一下,填完就搞一个。

@mwiker 正在开发中了,不会很久。
Heanes
2019-01-07 17:26:51 +08:00
这个比较可敬,有毅力有恒心
blue0125
2019-01-07 17:28:53 +08:00
支持带号转网了😂
vincentxue
2019-01-07 17:34:56 +08:00
@Heanes 还有很多朋友督促和帮助。
@blue0125 这个正则层面就没有办法了啊,文档也写明了。
iVeego
2019-01-07 17:35:34 +08:00
@livid 我记得之前你问过有无类似的服务。
fuxkcsdn
2019-01-07 17:40:02 +08:00
楼主有测试数据吗?
放到 regex101 上测试突然想到这个网站有个 regex library,搜索了下还真有

https://regex101.com/r/dnOlNH/1

虽然上面这种表达式不好看,但效率上比楼主写的高

p.s. regex101 那个表达式不完整,配合楼主的图或者下面的 wiki 改造下就行了
https://zh.wikipedia.org/wiki/%E4%B8%AD%E5%9B%BD%E5%86%85%E5%9C%B0%E7%A7%BB%E5%8A%A8%E7%BB%88%E7%AB%AF%E9%80%9A%E8%AE%AF%E5%8F%B7%E6%AE%B5
v2byy
2019-01-07 17:40:23 +08:00
已关注
beiyu
2019-01-07 17:57:15 +08:00
难得一见的好东西 mark 了
struggletoday
2019-01-07 18:00:46 +08:00
star
NonClockworkChen
2019-01-07 18:07:52 +08:00
这个轮子会把成千上万的轮子扼杀,star。
0312birdzhang
2019-01-07 18:51:43 +08:00
star star,好东西
vincentxue
2019-01-07 20:15:01 +08:00
@fuxkcsdn

Hi,你点每个正则的链接,进去之后看最下面的匹配项即可。

你这个正则我看了,也测试了一下,我这个要快 30%左右。

➜ Code sh run-benchmark.sh

Run the first round of testing.

2815.1209354401 - 9383624
3864.3181324005 - 7653307

Run the second round of testing.

2795.1259613037 - 9383624
3878.3061504364 - 7653307

Run the third round of testing.

2758.6340904236 - 9383624
3866.0190105438 - 7653307

Done.

主要原因我在兼顾方便的同时我还是尽量做了优化的。这里就不细讲了。那个正则里面有很多可以优化项,例如尽量减少分支条件,左侧优先,起始结尾描点优化等等。举个最简单的例子,他那个里面是 13、14、15 等等这样排序匹配的,我这里面 14、16 等使用频率低的号段我都放到最后面去了,这样能减少不必要的运算。

https://drive.google.com/file/d/1RkkRb7TSLYTdXoQaJmT8IVaRM-6UaPB1/view?usp=sharing 这是我刚才做的简单对比测试,包含 1000 万随机生成的手机号码。
cutlove
2019-01-07 20:47:02 +08:00
怎么 @ 站长,之前换手机号失败了,198 的号段
jiqing
2019-01-07 20:50:54 +08:00
这种好项目 star 又不会掉块肉
vincentxue
2019-01-07 21:31:57 +08:00
@cutlove 就 @Livid 就可以了。
whypool
2019-01-07 22:01:55 +08:00
1 开头 11 位数还要啥正则?
vincentxue
2019-01-07 22:15:36 +08:00
@Lax 165 号段已经加上了,感谢提醒。
vincentxue
2019-01-07 22:18:14 +08:00
@whypool 总有些人需要精确匹配的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/524624

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX