C# 正则表达式简单验证手机号码

小柊 发表于 2017年03月07日 23时39分41秒

老样子,废话少说一句话系列:

C#用下面的函数进行正则匹配:

#region 验证字符串是否为手机号码 + public static bool IsPhoneNumber(string phoneNumber)
/// <summary>
/// 验证字符串是否为手机号码
/// </summary>
/// <param name="phoneNumber">待验证字符串</param>
/// <returns>
/// 验证结果
/// <para> true  :输入字符串为有效的手机号码</para>
/// <para> false :输入字符串为无效的手机号码</para>
/// </returns>
public static bool IsPhoneNumber(string phoneNumber)
{
	return Regex.IsMatch(phoneNumber, @"^1(3[0-9]|5[0-9]|7[6-8]|8[0-9])[0-9]{8}$");
} 
#endregion

 

现在很多时候,网站都会需要用户提供自己的手机号码。不过很多时候用户会选择随便输入11位数字,如果去在提交时不及时发现,可能到时候就是白白调用一次短信发送接口。如果可以,我们后台开发者更希望能在用户提交时发现明显不合法的手机号码,从而阻止提交保存。那该怎么做呢。

 

之前翻看过别人做的项目代码,发现有些人在这里就是简单粗暴,他们判断用户提交的字符串是否为一个合法的字符串时,会写这么一个检验流程:

  1. 判断字符串长度是否为11位;
  2. 判断是否为为long(Int64)类型;
  3. 判断首字符是否为'1'。

 

然后就发现用户提交了一个小数(double),真是喜闻乐见。

 

那又有什么优雅的方法呢?

当然是有啊,不然我还专门写篇博客干什么,不过在讲方法之前,请先听我进行一定的科普。

我们所说的手机号码,专业名称为MDN(Mobile Directory Number,移动用户号码簿号码)

MDN采取E.164编码方式。MDN号码的结构如下:

MDN =CC + MAC + SN

其中:

  • CC(Country Code,国家码)

CC是用户所属国家代号,由2位数字组成。CC的资源由ITU(International Telecommunications Union,国际电信联盟)在全世界范围内,统一分配和管理。

也就是我们中国用的86。

  • MAC(Mobile Access Code,移动接入码)

识别移动用户所归属的移动通信网。由3位数字组成。

每个国家都可以授权一个或多个网络运营商组建并经营移动网络,MAC可以用于区分移动运营商;在号码资源不足时,可以为一个运营商分配多个MAC。

如:工信部为中国电信分配了153、189、133等号段。

  • SN(Subscriber Number,用户号码)

SN长度为8位,编码格式为H0H1H2H3ABCD。

H0H1H2H3:HLR识别码,由运营商统一分配。如, H0H1H2由总部统一分配到各省,H3由各省分配到本地网。

ABCD:移动用户号码,由各HLR自行分配。

 

以上来自百度百科《MDN (移动用户号码簿号码)》词条,略有修改

 

在咱们国家,手机号码属于公有资源,由国家相应部门进行管理,嘛,就是工信部,三大运营商只有从工信部里拿到号段,也就是上面说的MAC,才能向我们老百姓发放手机号。

 

那么现在工信部到底给三大家发放了哪几个号段了呢?这里有一张表格:

 

一般来说,上网卡只有数据流量功能,并没有语音通话功能,所以要从手机号段里毙掉,给上网卡发验证短信不开玩笑么~另外,虚拟运营商专属号段一般来说现在大多被不法分子用去干垃圾电话短信骚扰,所以也枪毙。

 

好,整理一下上面的表格和刚刚说的制约条件,可以得出以下表格:

表格里,绿色的为现在正在正常使用的合法号段;而红色的,属于现在还未分配的号段,对系统来说是非法号段。

 

由上图可知,一个简单验证手机号码函数,当用户输入了一个合法号段,函数就应该返回true,但如果输入了一个非法号段,函数就应该返回false。

该怎么做?把表格里的号段头设置为一个数组循环测试吗?

不,这不优雅!

来,我来给你一个优雅的,用正则表达式的简单验证函数:

#region 验证字符串是否为手机号码 + public static bool IsPhoneNumber(string phoneNumber)
/// <summary>
/// 验证字符串是否为手机号码
/// </summary>
/// <param name="phoneNumber">待验证字符串</param>
/// <returns>
/// 验证结果
/// <para> true  :输入字符串为有效的手机号码</para>
/// <para> false :输入字符串为无效的手机号码</para>
/// </returns>
public static bool IsPhoneNumber(string phoneNumber)
{
	return Regex.IsMatch(phoneNumber, @"^1(3[0-9]|5[0-9]|7[6-8]|8[0-9])[0-9]{8}$");
} 
#endregion

 

算上函数体,四行结束。注意:此函数只能验证11位中国大陆手机号码!

就问你优雅不优雅?

 

之所以要写这个,是因为自己在做项目的时候碰到了这种需求,但是百度一下就没一个称心的答案……

总之,用这个函数可以简单的验证用户是否输入了正确格式的号码。不过至于这个号码究竟是真的假的……嗯,还是发验证码去测试吧。

 

2017年3月9日 补充

有朋友在评论区里说可以用\d代替[0-9]以减少长度,这确实是可行的。不过我个人认为我在文章正文中的那种写法更贴近阅读习惯,如果后期有什么特殊调整(比如17X号段又放号了,其他号段退网了balabala)工作量也会稍微少些。

综上所述,如果你想追求可读性,可以用我的写法,如果你追求简洁,可以使用:

@"^1(3\d|5\d|7[6-8]|8\d)\d{8}$"

 

根据您个人喜好决定。

 

小柊

2017年3月7日 23:14:26

相关文章

  1 条评论发布于 “C# 正则表达式简单验证手机号码

  1. 大厨师
    2017年3月8日 at 08:41

    [0-9]用\d替代,正则会更短一点

发表评论

电子邮件地址不会被公开。 必填项已用*标注