• 正则表达式之密码验证


    对于门户网站,用户注册或修改密码时,需要有正则表达式验证密码,根据安全级别不同,网站会设置不同基本的密码正则表达式。
    而此文主要通过一个实例,来讲解密码正则表达式中使用的特殊正则语法,如?! 、?= 等(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}。
    . 匹配除" "之外的任何单个字符。若要匹配包括" "在内的任意字符,请使用诸如"[sS]"之类的模式。
    (?=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
    
  • 相关阅读:
    直拍反手拉球引拍位置及发力技巧
    话说多球 --  乒在民间
    直板横打不稳定,总是出界的可能原因 -- 乒在民间
    【hihocoder 1424】 Asa's Chess Problem(有源汇上下界网络流)
    【HDU 6036】Division Game (NTT+数学)
    【hdu 4658】Integer Partition (无序分拆数、五边形数定理)
    【hdu 5628】Clarke and math (Dirichlet卷积)
    【hdu6188】Duizi and Shunzi(贪心)
    【hdu6186】CS Course(前缀后缀异或)
    【hdu6185】Covering(骨牌覆盖)
  • 原文地址:https://www.cnblogs.com/johnleo/p/password_regex.html
Copyright © 2020-2023  润新知