正则表达式

正则表达式三叉戟

正则表达式的各个部分可以由三个不同的组件组成:

  1. 锚点

  2. 字符集

  3. 修饰符

这三部分构成了正则表达式的三叉戟!

 

锚点

锚点指定个各行的模式位置。下面是两个最重要的锚点:

  • ^(插入符号)将模式固定到行首。例如,模式^1 匹配以 1 开头的任意行。

  • $(美元符)将模式固定到句尾。例如,9$匹配以 9 结尾的任意行。

注意,在以上两种情况下,锚点必须分别位于模式的开头和结尾。^1 匹配行首的 1,但 1^匹配后跟^的 1。类似地,1$匹配以 1 结尾的行,但$1 匹配一个该行任意位置后跟 1 的美元符号。

		String reg = "^[a-zA-Z0-9].*"; // 以字母或者数字开头的任意字符串
		String a1 = "4abcd123";
		String a2 = "aabcd123";
		System.out.println(a1.matches(reg)); // true
		System.out.println(a2.matches(reg)); // true
		
		String reg2 = ".*[a-zA-Z0-9]$"; // 以字母或者数字结尾的任意字符串
		String b1 = "你好helloworld";
		String b2 = "abcdef123";
		System.out.println(b1.matches(reg2)); // true
		System.out.println(b2.matches(reg2)); // true

字符集  更多字符集:https://www.runoob.com/java/java-regular-expressions.html

三叉戟的第二部分:字符集。字符集是正则表达式的基础。单个字符,比如 a,是最基本的字符集(一组元素)。但是 [0-9] 等正则表达式可以匹配任何一个数字,或者如果你能回想到 *的含义,则可以制作模式 [0-9][0-9](这个模式匹配的内容留给读者作为练习)。

其他一些重要的字符集:

  • [0-9] 匹配 0…9 中的任何一个数字

  • [a-z] 匹配任何小写字母

  • [A-Z] 匹配任何大写字母

  • 忽略大小写 
    (?i)abc 表示abc都忽略大小写
    a(?i)bc 表示bc忽略大小写
    a((?i)b)c 表示只有b忽略大小写 

我们还可以对多个字符集进行组合:

  • [A-Za-z0-9] 匹配任何大小写字母和单个数字。

练习:忽略大小写 

		// (?i)abc 表示abc都忽略大小写
		String reg1 = "(?i)[abc]{5}";
		String aa1 = "abcAB";
		System.out.println(aa1.matches(reg1));	// true
		
		// a(?i)bc 表示bc忽略大小写
		String reg2 = "[a-z](?i)[abc]{5}";
		String bb1 = "Aabcab";
		String bb2 = "aabcab";
		String bb3 = "aABCAB";
		System.out.println(bb1.matches(reg2)); // false
		System.out.println(bb2.matches(reg2)); // true
		System.out.println(bb3.matches(reg2)); // true
		
		// a((?i)b)c 表示只有b忽略大小写
		String reg3 = "[a-z]((?i)[abc]{5})[A-Z]";
		String cc1 = "AABCABA";
		String cc2 = "AabcabA";
		String cc3 = "aABCABA";
		String cc4 = "aabcabA";
		System.out.println(cc1.matches(reg3)); // false
		System.out.println(cc2.matches(reg3)); // false
		System.out.println(cc3.matches(reg3)); // true
		System.out.println(cc4.matches(reg3)); // true

 

修饰符

此部分内容没有深入展开,以前面遇到的一个修饰符 *(星号)为例。修饰符改变它前面字符的含义。还有很多其他的修饰符,但以* 为例进行讨论是一个很好的开始。

  1. .(点)匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用像"(.|\n)"的模式。
  2. * (星号)匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
  3. +  匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。

练习:测试 .* 和 .+ 的区别

        String reg1 = ".*";
        String reg2 = ".+";
        
        String aa1 = "abc34?";
        String aa2 = "1";
        String aa3 = "";
        
        System.out.println(aa1.matches(reg1)); // true
        System.out.println(aa1.matches(reg2)); // true
        System.out.println(aa2.matches(reg1)); // true
        System.out.println(aa2.matches(reg2)); // true
        System.out.println(aa3.matches(reg1)); // true
        System.out.println(aa3.matches(reg2)); // false

 

总结

回顾一下这篇博客的内容:

  • 正则表达式的基本功能;

  • 正则表达式的三个主要组件:锚点、字符集和修饰符。

  •  .(点)、*(星号)、^(插入符)和$(美元符号)。

  • 一些字符集 [0-9]、[a-z]、[A-Z] 和它们的组合。

 

疑问:

[com,cn,net]{1,3}    啥意思

 

练习

1.先来几个简单的

		// 只包含数字
		String reg1 = "[0-9]+";
		String aa1 = "";
		String aa2 = "1";
		System.out.println(aa1.matches(reg1)); // false 
		System.out.println(aa2.matches(reg1)); // true
		
		// 只包含中文
		String reg2 = "[\\u4E00-\\u9FA5]+";
		String bb1 = "abc,123";
		String bb2 = "你好世界";
		System.out.println(bb1.matches(reg2)); // false
		System.out.println(bb2.matches(reg2)); // true
		
		// 只包含字母数字中文
		String reg3 = "[a-zA-Z0-9\\u4E00-\\u9FA5]+";
		String cc1 = "abc123天明";
		System.out.println(cc1.matches(reg3)); // true
		
		// 包含了逗号,
		String reg4 = ".*[,].*";
		String dd1 = "abc123";
		String dd2 = ",";
		String dd3 = "23,";
		String dd4 = ",12";
		String dd5 = "12,34";
		System.out.println(dd1.matches(reg4)); // false
		System.out.println(dd2.matches(reg4)); // true
		System.out.println(dd3.matches(reg4)); // true
		System.out.println(dd4.matches(reg4)); // true
		System.out.println(dd5.matches(reg4)); // true

2.只包含5个字符,且只能是字母或者数字

		String reg = "^[a-zA-Z0-9]{5}$";
		String aa1 = "abc123";
		String aa2 = "abc1";
		String aa3 = "abc1_";
		String aa4 = "abc1李";
		String aa5 = "abc1a";
		
		System.out.println(aa1.matches(reg));	// false
		System.out.println(aa2.matches(reg));	// false
		System.out.println(aa3.matches(reg));	// false
		System.out.println(aa4.matches(reg));	// false
		System.out.println(aa5.matches(reg));	// true

3.邮箱验证:

        // 1.简易版:类似 ?????@?????.???
        String reg1 = "^.+@.+(\\..+){1,}$";
        String aa1 = "fushb@163.com";
        String aa2 = "fushb@163.com.com.com";
        String aa3 = "@@@李六放散阀@163.com.com.第一集";
        System.out.println(aa1.matches(reg1));	// true
        System.out.println(aa2.matches(reg1));	// true
        System.out.println(aa3.matches(reg1));	// true
        
        // 2.加强版: 
        /*
		 * 解析:  ^ 匹配开始 $ 匹配结束 [a-z] E-Mail前缀必需是一个英文字母开头
		 * (?i) 构成一个不区分大小写的正则表达式
		 * ([a-z0-9]*[-_]?[a-z0-9]+)*
		 * 和_a_2、aaa11、_1_a_2匹配,和a1_、aaff_33a_、a__aa不匹配,如果是空字符,也是匹配的,*表示0个或者多个。
		 * 表示0个或多个前面的字符. [a-z0-9]* 匹配0个或多个英文字母或者数字 [-_]? 匹配0个或1“-”,因为“-”不能连续出现 [a-z0-9]+
		 * 匹配1个或多个英文字母或者数字,因为“-”不能做为结尾
		 * 
		 * @ 必需有个有@ ([a-z0-9]*[-_]?[a-z0-9]+)+
		 * 见上面([a-z0-9]*[-_]?[a-z0-9]+)*解释,但是不能为空,+表示一个或者为多个。 [\.] 将特殊字符(.)当成普通字符
		 * [a-z]{2,3} 匹配2个至3个英文字母,一般为com或者net等. ([\.][a-z]{2})?
		 * 匹配0个或者1个[\.][a-z]{2}(比如.cn等) 不知道一般.com.cn最后部份是不是都是两位的,如果不是请修改{2}为{起始字数,结束字数}
		 */
        String reg2 = "^[a-z]([a-z0-9]*[-_]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\\.][a-z]{2,3}([\\.][a-z]{2})?$";
        String bb0 = "tian李@con.cn";	// 除了@、.(点)、-(横杆) ,只能包含字母和数字
        String bb1 = "1ushb@con.cn"; 	// 必须以字母开头
        String bb2 = "1ushb@con.12";	// 必须以字母结束
        String bb3 = "fushb@con.cnaa";	// 必须以2个或者3个字母结束
        String bb4 = "fushb@con.cna";
        String bb5 = "fushb@163.com";
        System.out.println(bb0.matches(reg2)); // false
        System.out.println(bb1.matches(reg2)); // false
        System.out.println(bb2.matches(reg2)); // false
        System.out.println(bb3.matches(reg2)); // false
        System.out.println(bb4.matches(reg2)); // true
        System.out.println(bb5.matches(reg2)); // true
        
        // 3.再来一个加强版吧
		/*
		 * 解析也来一份吧 
		 * [0-9a-zA-Z_]+. 字母数字下划线至少一个再加一个任何字符
		 * (?:[0-9a-zA-Z_]+.)+ 上面的至少一个
		 * @[0-9a-zA-Z]{1,13} 一个@和1-13个字母或者数字
		 * [com,cn,net]{1,3} com,cn,net 这10个字符,需要出现1到3次才行,所以这种表达有点问题
		 */
		String reg3 = "(?:[0-9a-zA-Z_]+.)+@[0-9a-zA-Z]{1,13}\\.[com,cn,net]{1,3}";
		String cc1 = "_@qq.com";
        String cc2 = "a李@qq.www";
        String cc3 = "_李@qq.cc";
        String cc4 = "_李@qq.oo";
        String cc5 = "a_@163.com";
        System.out.println(cc1.matches(reg3));	// false
        System.out.println(cc2.matches(reg3));	// false
        System.out.println(cc3.matches(reg3));	// true
        System.out.println(cc4.matches(reg3));	// true
        System.out.println(cc5.matches(reg3));	// true
        
        // 4.将reg3改进
        String reg4 = "(?:[0-9a-zA-Z_]+.)+@[0-9a-zA-Z]{1,13}\\.(?:com|cn|net)";
        String dd1 = "_@qq.com";
        String dd2 = "a李@qq.www";
        String dd3 = "_李@qq.cc";
        String dd4 = "_李@qq.oo";
        String dd5 = "a_@163.com";
        System.out.println(dd1.matches(reg4));	// false
        System.out.println(dd2.matches(reg4));	// false
        System.out.println(dd3.matches(reg4));	// false
        System.out.println(dd4.matches(reg4));	// false
        System.out.println(dd5.matches(reg4));	// true

4.手机号码验证

简易版:

public class PhoneFormatCheckUtils{

    private static final String Reg = "^[1][0-9]{10}$";
   
    public static boolean checkPhone(String phone) {
    	return phone.matches(Reg);
    }
    
    public static void main(String[] args) {
    	System.out.println(checkPhone("18410441200"));
	}
}

加强版: 

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
 
public class PhoneFormatCheckUtils{
	/**
     * ^ 匹配输入字符串开始的位置
     * \d 匹配一个或多个数字,其中 \ 要转义,所以是 \\d
     * $ 匹配输入字符串结尾的位置
     */
    private static final Pattern HK_PATTERN = Pattern.compile("^(5|6|8|9)\\d{7}$");
    private static final Pattern CHINA_PATTERN = Pattern.compile("^((13[0-9])|(14[0,1,4-9])|(15[0-3,5-9])|(16[2,5,6,7])|(17[0-8])|(18[0-9])|(19[0-3,5-9]))\\d{8}$");
    private static final Pattern NUM_PATTERN = Pattern.compile("[0-9]+");
    
    /**
     * 大陆号码或香港号码均可
     */
    public static boolean isPhoneLegal(String str) throws PatternSyntaxException {
        return isChinaPhoneLegal(str) || isHKPhoneLegal(str);
    }
 
    /**
     * 大陆手机号码11位数,匹配格式:前三位固定格式+后8位任意数
     * 此方法中前三位格式有:
     * 13+任意数
     * 145,147,149
     * 15+除4的任意数(不要写^4,这样的话字母也会被认为是正确的)
     * 166
     * 17+3,5,6,7,8
     * 18+任意数
     * 198,199
     */
    public static boolean isChinaPhoneLegal(String str) throws PatternSyntaxException {
        Matcher m = CHINA_PATTERN.matcher(str);
        return m.matches();
    }
 
    /**
     * 香港手机号码8位数,5|6|8|9开头+7位任意数
     */
    public static boolean isHKPhoneLegal(String str) throws PatternSyntaxException {
 
        Matcher m = HK_PATTERN.matcher(str);
        return m.matches();
    }
 
    /**
     * 判断是否是正整数的方法
     */
    public static boolean isNumeric(String string) {
        return NUM_PATTERN.matcher(string).matches();
    }
}

5.Java 判断密码是否是大小写字母、数字、特殊字符中的至少三种(不是原创)

public class CheckPassword {
    //数字
    public static final String REG_NUMBER = ".*\\d+.*";
    //小写字母
    public static final String REG_UPPERCASE = ".*[A-Z]+.*";
    //大写字母
    public static final String REG_LOWERCASE = ".*[a-z]+.*";
    //特殊符号
    public static final String REG_SYMBOL = ".*[~!@#$%^&*()_+|<>,.?/:;'\\[\\]{}\"]+.*";
 
    public static boolean checkPasswordRule(String password){
        //密码为空或者长度小于8位则返回false
        if (password == null || password.length() <8 ) {
        	return false;
        }
        int i = 0;
        if (password.matches(REG_NUMBER)) i++;
        if (password.matches(REG_LOWERCASE))i++;
        if (password.matches(REG_UPPERCASE)) i++;
        if (password.matches(REG_SYMBOL)) i++;
        if (i  < 3 )  return false;
 
        return true;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值