题记:给定任意的6位数字,按以下规则返回其类型。例如275678,满足后四位连续,属于第3类。
数字类型 规则 规则描述 例子
由于每组数字都有其特点,采用正则表达式来解决。单个数字重复用{N}来表示,多个数字重复用分组加{N}表示。代码如下
package com.like.regex;
import java.util.HashMap;
import java.util.Map;
/**
* @author: ly
* @created: 2011-8-14
* @version: v1.0
*/
public class SixNumberGenerator {
public static final Long MIN_NUMBER = 1000000L; // 6位的最小数+前缀1
public static final Long MAX_NUMBER = 1999999L; // 6位的最大数+前缀1
public static Map<String, String> statusMap = new HashMap<String, String>(); // 号码类别map
// 1类
// 后五位相同
private static String regex6 = "[0-9]{1}([\\d])\\1{4}";
// 六位连续
private static String regex7 = "(?:(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){5}|(?:9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){5})\\d";
// 2类
// 六位三三相同
private static String regex8 = "([\\d])\\1{2}([\\d])\\2{2}";
// 六位三三联号
private static String regex9 = "([0-9]{3})\\1{1}";
// 后四位相同
private static String regex10 = "[0-9]{2}([\\d])\\1{3}";
// 前五位相同
private static String regex11 = "([\\d])\\1{4}[0-9]{1}";
// 后五位连续
private static String regex12 = "[0-9]{1}(?:(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=0)){2,}|(?:0(?=9)|9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){4})\\d";
// 六位中两两相同(1)
private static String regex13 = "([0-9]{2})\\1{2}";
// 后六位中两两相同(2)
private static String regex14 = "([\\d])\\1{1}([\\d])\\2{1}([\\d])\\3{1}";
// 3类
// 六位中前三位和后三位重复
private static String regex15 = "([\\d])\\1{3}[\\d]{2}";
// 中间四位相同
private static String regex16 = "[\\d]{1}([\\d])\\1{3}[\\d]{1}";
// 后四位连续
private static String regex17 = "[0-9]{2}(?:(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=0)){2,}|(?:0(?=9)|9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){3})\\d";
// 后六位中,除后四位外,任意四位相同
// // 用函数来完成
// 仍用正则表达式来验证
private static String regex172 = "\\d*(\\d)(\\d*\\1){3,}\\d*";
// 4类
// 后四位中后三位相同
private static String regex18 = "[\\d]{2}[\\d]{1}([\\d])\\1{2}";
// 后四位中前三位相同
private static String regex19 = "[\\d]{2}([\\d])\\1{2}[\\d]{1}";
// 后四位交替重叠(1)
private static String regex20 = "[\\d]{2}([\\d]{2})\\1{1}";
// 后四位交替重叠(2)
private static String regex21 = "[\\d]{2}([\\d])\\1{1}([\\d])\\2{1}";
// 5类
// 其它数字
public SixNumberGenerator() {
statusMap.put("1", "一类");
statusMap.put("2", "二类");
statusMap.put("3", "三类");
statusMap.put("4", "四类");
statusMap.put("5", "五类");
}
public void testGenerateNumberPool() {
System.out.println("数字" + " " + "数字类别" + " " + "类别中文描述" + " ");
for (Long i = MIN_NUMBER; i.intValue() <= MAX_NUMBER.intValue(); i++) {
// 6位数字
String number = String.valueOf(i.toString().substring(1));
String status = this.getStatus(number);
String statusDesc = this.getStatusDesc(status);
System.out.println(number + " " + status + " " + statusDesc
+ " ");
}
}
/**
* 获取号码的类型,匹配方式:正则表达式
*
* @param cn
* @return
*/
private String getStatus(String cn) {
String ret = "-1";
// 匹配正则表达式
if (cn.matches(regex6) || cn.matches(regex7)) {
ret = "1";
} else if (cn.matches(regex8) || cn.matches(regex9)
|| cn.matches(regex10) || cn.matches(regex11)
|| cn.matches(regex12) || cn.matches(regex13)
|| cn.matches(regex14)) {
ret = "2";
} else if (cn.matches(regex15) || cn.matches(regex16)
|| cn.matches(regex17) || cn.matches(regex172)) {
ret = "3";
} else if (cn.matches(regex18) || cn.matches(regex19)
|| cn.matches(regex20) || cn.matches(regex21)) {
ret = "4";
} else {
ret = "5";
}
return ret;
}
/**
* 状态中文描述
*
* @param status
* @return
*/
private String getStatusDesc(String status) {
return statusMap.get(status);
}
/**
* 判断六位数字中,除后四位外,任意四位相同 后改用正则表达式匹配
*
* @param cs
* @return
*/
private boolean csNumber(String cs) {
boolean ret = false;
String s1 = cs.substring(0, 1);
String s2 = cs.substring(1, 2);
String[] ss1 = cs.split(s1);
String[] ss2 = cs.split(s2);
if (ss1.length >= 4 || ss2.length >= 4) {
ret = true;
}
return ret;
}
public static void main(String[] args) {
SixNumberGenerator test = new SixNumberGenerator();
test.testGenerateNumberPool();
}
}
上面一系列正则表达式中,难点有两个,捕获组和非捕获组:
其中捕获组:
\num | 对捕获组的反向引用。其中 num 是一个正整数。 | (\w)(\w)\2\1 匹配abba |
非捕获组:
(?:pattern) | 匹配pattern,但不捕获匹配结果。 | 'industr(?:y|ies) 匹配'industry'或'industries'。 |
(?=pattern) | 零宽度正向预查,不捕获匹配结果。 | 'Windows (?=95|98|NT|2000)' 匹配 "Windows2000" 中的 "Windows" 不匹配 "Windows3.1" 中的 "Windows"。 |
参考:http://blog.csdn.net/zfq642773391/article/details/5555602
http://www.cnblogs.com/wuhong/archive/2011/02/18/1957017.html
jdk1.6API:java.util.regex类 Pattern的介绍