正則表達式之密碼驗證


對於門戶網站,用戶注冊或修改密碼時,需要有正則表達式驗證密碼,根據安全級別不同,網站會設置不同基本的密碼正則表達式。
而此文主要通過一個實例,來講解密碼正則表達式中使用的特殊正則語法,如?! 、?= 等(Java代碼驗證)。

密碼強度要求

  1. 至少包含一個數字,一個字母,一個特殊字符
  2. 密碼長度在8~18之間

特殊正則語法

  1. Java 8 API中Pattern類對特殊正則語法的描述
  2. 正則字符詳細說明
字符 說明
* 零次或多次匹配前面的字符或子表達式。例如,zo* 匹配"z"和"zoo"。* 等效於 {0,}。
+ 一次或多次匹配前面的字符或子表達式。例如,"zo+"與"zo"和"zoo"匹配,但與"z"不匹配。+ 等效於 {1,}。
? 零次或一次匹配前面的字符或子表達式。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效於 {0,1}。
. 匹配除"\r\n"之外的任何單個字符。若要匹配包括"\r\n"在內的任意字符,請使用諸如"[\s\S]"之類的模式。
(?=pattern) 執行正向預測先行搜索的子表達式,該表達式匹配處於匹配 pattern 的字符串的起始點的字符串。它是一個非捕獲匹配,即不能捕獲供以后使用的匹配。例如,'Windows (?=95
(?!pattern) 執行反向預測先行搜索的子表達式,該表達式匹配不處於匹配 pattern 的字符串的起始點的搜索字符串。它是一個非捕獲匹配,即不能捕獲供以后使用的匹配。例如,'Windows (?!95

密碼正則表達式

  1. 正向斷言: regex = ^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$_&*+-])[0-9a-zA-Z!@#$_&*+-]{8,18}$
    解釋:根據上面的正則字符說明,先分析(?=.*[0-9]), 其中?=pattern01是正向先行搜索子表達,不獲取匹配,其實可以理解為斷言匹配的string能夠用pattern01匹配到子表達,如果斷言成功,則就用剩下剩余的regex去匹配此string,否則regex即匹配不成功;
    .*[0-9]表示匹配以數字結尾的字符串(即整個待匹配的字符串包含數字),所以(?=.*[0-9])表示為斷言字符串包含數字,(?=.*[a-zA-Z])斷言字符串包含字母,(?=.*[!@#$_&*+-])斷言字符創包含特殊字符;若這三個斷言成功,就限定了string至少含有數字、字母、特殊字符;
    而最后的[0-9a-zA-Z!@#$_&*+-]就限定了只能包含數字、字母、特殊字符。
  2. 反向斷言: regex = ^(?![a-zA-Z0-9]+$)(?![a-zA-Z!@#$%^_&*]+$)(?![0-9!@#$%^_&*]+$)[a-zA-Z0-9!@#$%^_&*]{8,18}$
    解釋:(?![a-zA-Z0-9]+$)表示不能只包含數字和字母,同理,三個反向斷言也可以限定至少包含一個數字、字母、特殊字符

代碼測試

public class HelloWorld {
	public static void main(String []args) {
//		testRegexPositive();
		testRegexNegative();
	}

	public static void testRegexPositive() {
		System.out.println("=====testRegexPositive====");
		String reg = "^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$_&*+-])[0-9a-zA-Z!@#$_&*+-]{8,18}$";
		
		Pattern pattern = Pattern.compile(reg);
		
		Scanner sc = new Scanner(System.in);
		while( sc.hasNext() ) {
			String str = sc.nextLine();
			Matcher matcher = pattern.matcher(str);
			if ( matcher.matches() ) {
				System.out.println( str + " matched! length = " + String.valueOf(str.length()) );
			} else {
				System.out.println( str + " not matched! length = " + String.valueOf(str.length()) );
			}
		}
	}
	
	public static void testRegexNegative() {
		System.out.println("=====testNegative====");
		String reg = "^(?![a-zA-Z0-9]+$)(?![a-zA-Z!@#$%^_&*]+$)(?![0-9!@#$%^_&*]+$)[a-zA-Z0-9!@#$%^_&*]{8,18}$";
		
		Pattern pattern = Pattern.compile(reg);
		
		Scanner sc = new Scanner(System.in);
		while( sc.hasNext() ) {
			String str = sc.nextLine();
			Matcher matcher = pattern.matcher(str);
			if ( matcher.matches() ) {
				System.out.println( str + " matched! length = " + String.valueOf(str.length()) );
			} else {
				System.out.println( str + " not matched! length = " + String.valueOf(str.length()) );
			}
		}
	}
}
  1. 正向測試結果
=====testRegexPositive====
1234asdf
1234asdf not matched! length = 8
asdf@w1
asdf@w1 not matched! length = 7
asdf@w12
asdf@w12 matched! length = 8
  1. 反向測試結果
=====testNegative====
1234asdf
1234asdf not matched! length = 8
1234asd
1234asd not matched! length = 7
1234asd#
1234asd# matched! length = 8


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM