1. 程式人生 > >正則表示式(靚號過濾)

正則表示式(靚號過濾)

一般公司在開發一類對的號碼時,會預留一些號碼給以後升級的會員使用,比如旺旺靚號,QQ號等,採用正則表示式實現較好,通過規則引擎的後臺頁面做成實時可配置的也是不錯的選擇。

一. 一般會有如下的正則需求

程式碼如下:

Java程式碼  收藏程式碼
  1. public class CreditCodeRegexValidateStategyServiceImpl implements CreditCodeValidateStategyService {  
  2.     private static List<String> levitPatterns;  
  3.     static synchronized
     private void init() {  
  4.         if (levitPatterns == null) {  
  5.             levitPatterns = new ArrayList<String>();  
  6.         } else {  
  7.             return;  
  8.         }  
  9.         // 手機號、生日號、跟公司業務相關的號碼  
  10.      levitPatterns.add("^(0|13|15|18|168|400|800)[0-9]*$");  
  11.         levitPatterns.add("^\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$"
    );  
  12.         levitPatterns.add("^\\d*(1688|2688|2088|2008|5188|10010|10001|666|888|668|686|688|866|868|886|999)\\d*$");  
  13.         // 重複號碼,鏡子號碼  
  14.      levitPatterns.add("^(<a>\\d)(\\d)(\\d)\\1\\2\\3$");  
  15. </a>        levitPatterns.add("^(\\d)(\\d)(\\d)\\3\\2\\1$");  
  16.         // AABB  
  17.         levitPatterns.add("^\\d*(\\d)\\1(\\d)\\2\\d*$"
    );  
  18.         // AAABBB  
  19.         levitPatterns.add("^\\d*(\\d)\\1\\1(\\d)\\2\\2\\d*$");  
  20.         // ABABAB  
  21.         levitPatterns.add("^(\\d)(\\d)\\1\\2\\1\\2\\1\\2$");  
  22.         // ABCABC  
  23.         levitPatterns.add("^(\\d)(\\d)(\\d)\\1\\2\\3$");  
  24.         // ABBABB  
  25.         levitPatterns.add("^(\\d)(\\d)\\2\\1\\2\\2$");  
  26.         // AABAAB  
  27.         levitPatterns.add("^(\\d)\\1(\\d)\\1\\1\\2$");  
  28.         // 4-8 位置重複  
  29.         levitPatterns.add("^\\d*(\\d)\\1{2,}\\d*$");  
  30.         // 4位以上 位遞增或者遞減(7890也是遞增)  
  31.         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");  
  32.         // 不能以 518 、918 結尾  
  33.         levitPatterns.add("^[0-9]*(518|918)$");  
  34.     }  
  35.     @Override  
  36.     public boolean isAllow(String input) {  
  37.         Assert.notNull(input);  
  38.         return !RegexUtil.contains(input, levitPatterns);  
  39.     }  
  40.     static {  
  41.         init();  
  42.     }  

對於以上正則,前面的大多人都很熟悉了,這裡主要講位置查詢和前後向查詢,即如下兩種號碼的判斷

Java程式碼  收藏程式碼
  1. // ABBABB  
  2.       levitPatterns.add("^(\\d)(\\d)\\2\\1\\2\\2$");  
Java程式碼  收藏程式碼
  1. // 4位以上 位遞增或者遞減(7890也是遞增)  
  2.       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程式碼  收藏程式碼
  1. public class RegexUtil {  
  2.     private static PatternCompiler compiler = new Perl5Compiler();  
  3.     private static PatternMatcher  matcher  = new Perl5Matcher();  
  4.     private static Pattern         pattern  = null;  
  5.     /** 
  6.      * 根據正則過濾條件過濾 
  7.      *  
  8.      * @param input 
  9.      * @param levitPatterns 
  10.      * @return 
  11.      * @throws MalformedPatternException 
  12.      */  
  13.     public static boolean contains(String input, String patternString) {  
  14.         try {  
  15.             pattern = compiler.compile(patternString);  
  16.             if (matcher.contains(input, pattern)) {  
  17.                 return true;  
  18.             }  
  19.         } catch (MalformedPatternException e) {  
  20.             return false;  
  21.         }  
  22.         return false;  
  23.     }  
  24.     /** 
  25.      * 根據批量正則過濾條件過濾 
  26.      *  
  27.      * @param input 
  28.      * @param patternStrings 
  29.      * @return 
  30.      * @throws MalformedPatternException 
  31.      */  
  32.     public static boolean contains(String input, List<String> patternStrings) {  
  33.         for (Iterator<String> lt = patternStrings.listIterator(); lt.hasNext();) {  
  34.             if (contains(input, (String) lt.next())) {  
  35.                 return true;  
  36.             }  
  37.             continue;  
  38.         }  
  39.         return false;  
  40.     }  
  41. }