正則表示式(靚號過濾)
阿新 • • 發佈:2019-01-04
一般公司在開發一類對的號碼時,會預留一些號碼給以後升級的會員使用,比如旺旺靚號,QQ號等,採用正則表示式實現較好,通過規則引擎的後臺頁面做成實時可配置的也是不錯的選擇。
一. 一般會有如下的正則需求
程式碼如下:
Java程式碼- public class CreditCodeRegexValidateStategyServiceImpl implements CreditCodeValidateStategyService {
- private static List<String> levitPatterns;
-
static synchronized
- if (levitPatterns == null) {
- levitPatterns = new ArrayList<String>();
- } else {
- return;
- }
- // 手機號、生日號、跟公司業務相關的號碼
- levitPatterns.add("^(0|13|15|18|168|400|800)[0-9]*$");
-
levitPatterns.add("^\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$"
- levitPatterns.add("^\\d*(1688|2688|2088|2008|5188|10010|10001|666|888|668|686|688|866|868|886|999)\\d*$");
- // 重複號碼,鏡子號碼
- levitPatterns.add("^(<a>\\d)(\\d)(\\d)\\1\\2\\3$");
- </a> levitPatterns.add("^(\\d)(\\d)(\\d)\\3\\2\\1$");
- // AABB
-
levitPatterns.add("^\\d*(\\d)\\1(\\d)\\2\\d*$"
- // AAABBB
- levitPatterns.add("^\\d*(\\d)\\1\\1(\\d)\\2\\2\\d*$");
- // ABABAB
- levitPatterns.add("^(\\d)(\\d)\\1\\2\\1\\2\\1\\2$");
- // ABCABC
- levitPatterns.add("^(\\d)(\\d)(\\d)\\1\\2\\3$");
- // ABBABB
- levitPatterns.add("^(\\d)(\\d)\\2\\1\\2\\2$");
- // AABAAB
- levitPatterns.add("^(\\d)\\1(\\d)\\1\\1\\2$");
- // 4-8 位置重複
- levitPatterns.add("^\\d*(\\d)\\1{2,}\\d*$");
- // 4位以上 位遞增或者遞減(7890也是遞增)
- levitPatterns.add("(?:(?: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)){2,})\\d");
- // 不能以 518 、918 結尾
- levitPatterns.add("^[0-9]*(518|918)$");
- }
- @Override
- public boolean isAllow(String input) {
- Assert.notNull(input);
- return !RegexUtil.contains(input, levitPatterns);
- }
- static {
- init();
- }
對於以上正則,前面的大多人都很熟悉了,這裡主要講位置查詢和前後向查詢,即如下兩種號碼的判斷
Java程式碼- // ABBABB
- levitPatterns.add("^(\\d)(\\d)\\2\\1\\2\\2$");
- // 4位以上 位遞增或者遞減(7890也是遞增)
- levitPatterns.add("(?:(?: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)){2,})\\d");
位置查詢: \\2\\1\\2\\2 這部分代表的 第一個A 位置是1 第二個B位置是2,重複B則用\\2標識
後向查詢 ("(?:(?:0(?=1)| 對於連續號碼,?=表示往後看,要判斷0後面是1嗎,1後面是2嗎,如此反覆可以得到連續號碼
二. 使用 org.apache.oro.text.regex.Pattern 代替 java自身帶的partern,
為什麼拋棄java現有的API不用,而使用perl5規範的正則庫呢?他是最全面的正則表示式API,全面相容perl5,同時也是優化的最好的API之一,在未來的JDK版本中可能會看到的。
上面程式呼叫的正則程式碼如下:
Java程式碼- public class RegexUtil {
- private static PatternCompiler compiler = new Perl5Compiler();
- private static PatternMatcher matcher = new Perl5Matcher();
- private static Pattern pattern = null;
- /**
- * 根據正則過濾條件過濾
- *
- * @param input
- * @param levitPatterns
- * @return
- * @throws MalformedPatternException
- */
- public static boolean contains(String input, String patternString) {
- try {
- pattern = compiler.compile(patternString);
- if (matcher.contains(input, pattern)) {
- return true;
- }
- } catch (MalformedPatternException e) {
- return false;
- }
- return false;
- }
- /**
- * 根據批量正則過濾條件過濾
- *
- * @param input
- * @param patternStrings
- * @return
- * @throws MalformedPatternException
- */
- public static boolean contains(String input, List<String> patternStrings) {
- for (Iterator<String> lt = patternStrings.listIterator(); lt.hasNext();) {
- if (contains(input, (String) lt.next())) {
- return true;
- }
- continue;
- }
- return false;
- }
- }