正文
1[3|4|5|7|8|][0-9]{9}
为方便表达手机号,手机号中间经常有连字符(即减号'-'),形如:
186-1234-5678
为表达这种可选的连字符,表达式可以改为:
1[3|4|5|7|8|][0-9]-?[0-9]{4}-?[0-9]{4}
在手机号前面,可能还有0、+86或0086,和手机号码之间可能还有一个空格,比如:
018612345678
+86 18612345678
0086 18612345678
为表达这种形式,可以在号码前加如下表达式:
((0|\+86|0086)\s?)?
和邮编类似,如果为了抽取,也要在左右加环视边界匹配,左右不能是数字。所以,完整的表达式为:
(?
用Java表示的代码为:
public static Pattern MOBILE_PHONE_PATTERN = Pattern.compile(
"(? + "((0|\\+86|0086)\\s?)?" // 0 +86 0086
+ "1[3|4|5|7|8|][0-9]-?[0-9]{4}-?[0-9]{4}" // 186-1234-5678
+ "(?![0-9])"); // 右边不能有数字
固定电话
不考虑分机,中国的固定电话一般由两部分组成:区号和市内号码,区号是3到4位,市内号码是7到8位。区号以0开头,表达式可以为:
0[0-9]{2,3}
市内号码表达式为:
[0-9]{7,8}
区号可能用括号包含,区号与市内号码之间可能有连字符,如以下形式:
010-62265678
(010)62265678
整个区号是可选的,所以整个表达式为:
(\(?0[0-9]{2,3}\)?-?)?[0-9]{7,8}
再加上左右边界环视,完整的Java表示为:
public static Pattern FIXED_PHONE_PATTERN = Pattern.compile(
"(? + "(\\(?0[0-9]{2,3}\\)?-?)?" // 区号
+ "[0-9]{7,8}"// 市内号码
+ "(?![0-9])"); // 右边不能有数字
日期
日期的表示方式有很多种,我们只看一种,形如:
2017-06-21
2016-11-1
年月日之间用连字符分隔,月和日可能只有一位。
最简单的正则表达式可以为:
\d{4}-\d{1,2}-\d{1,2}
年一般没有限制,但月只能取值1到12,日只能取值1到31,怎么表达这种限制呢?
对于月,有两种情况,1月到9月,表达式可以为:
0?[1-9]
10月到12月,表达式可以为:
1[0-2]
所以,月的表达式为:
(0?[1-9]|1[0-2])
对于日,有三种情况:
-
1到9号,表达式为:0?[1-9]
-
10号到29号,表达式为:[1-2][0-9]
-
30号和31号,表达式为:3[01]
所以,整个表达式为:
\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|3[01])
加上左右边界环视,完整的Java表示为:
public static Pattern DATE_PATTERN = Pattern.compile(
"(? + "\\d{4}-" // 年
+ "(0?[1-9]|1[0-2])-" // 月
+ "(0?[1-9]|[1-2][0-9]|3[01])"// 日
+ "(?![0-9])"); // 右边不能有数字