什么是正则表达式呢?我们先来看个案例:
需求:假如现在要求校验一个qq号码是否正确。 规则:6位及20位之内,0不能在开头,必须全部是数字。
我们先用以前的写法:
String qq = "123456789";
System.out.println(checkQQ(qq));
// 以前的写法
public static boolean checkQQ(String qq) {
// 规则:6到20以内,0不能开头,必须全部是数字
int len = qq.length();
if (len < 6 || len > 20) {
return false;
}
// 0不能在开头
if (qq.startsWith("0")) {
return false;
}
// 必须全部是数字
for (int i = 0; i < qq.length(); i++) {
char c = qq.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
哇,这是不是好麻烦呀?那我们用正则表达式看一下:
System.out.println(qq.matches("[1-9]\\d{5,19}"));
一行代码直接搞定了,怎么样,是不是很方便呀!下面我们一起来学习一下吧:
正则表达式可以校验字符串是否满足一定的规则,并用来校验数据格式的合法性。
- 正则表达式作用
- 校验字符串是否满足规则
- 在一段文本中查找满足要求的内容
我们来实操一下吧:
- 只能是a b c (只能匹配一个字符)
System.out.println("a".matches( "[abc]"));// true
System.out.println("z".matches("[abc]"));// false
System.out.println("ab".matches("[abc]"));// false
- 不能出现a b c (只能匹配一个字符)
System.out.println("a".matches( "[^abc]"));// false
System.out.println("z".matches( "[^abc]"));// true
System.out.println("zz".matches( "[^abc]"));// false
System.out.println("zz".matches( "[^abc][^abc]"));// true
- a到z A到Z(包括头尾的范围) (只能匹配一个字符)
System.out.println("a".matches( "[a-zA-Z]"));//true
System.out.println("z".matches( "[a-zA-Z]"));//true
System.out.println("aa".matches( "[a-zA-Z]"));//false
System.out.println("zz".matches( "[a-zA-Z]"));//false
System.out.println("0".matches( "[a-zA-Z]"));//false
System.out.println("0".matches( "[a-zA-Z0-9]"));//true
- [a-d[m-p]] a到d,或m到p (只能匹配一个字符)
System.out.println("a".matches("[a-d[m-p]]"));//true
System.out.println("d".matches("[a-d[m-p]]"));//true
System.out.println("m".matches("[a-d[m-p]]"));//true
System.out.println("p".matches("[a-d[m-p]]"));//true
System.out.println("e".matches("[a-d[m-p]]"));//false
System.out.println("0".matches("[a-d[m-p]]"));//false
- [a-z&&[def]]a-z和def的交集。为:d,e,f (只能匹配一个字符)
System.out.println("a".matches("[a-z&[def]]"));//false
System.out.println("d".matches("[a-z&[def]]"));//true
System.out.println("0".matches("[a-z&[def]]"));//false
- [a-z&&[^bc]]a-z和非bc的交集。(等同于[ad-z]) (只能匹配一个字符)
System.out.println("a".matches( "[a-z&&[^bc]]")); //true
System.out.println("b".matches( "[a-z&&[^bc]]")); //false
System.out.println("0".matches( "[a-z&&[^bc]]")); //false
- [a-z&&[^m-p]] a到z和除了m到p的交集。(等同于[a-lg-z]) (只能匹配一个字符)
System.out.println("a".matches("[a-z&&[^m-p]]"));//true
System.out.println("m".matches("[a-z&&[^m-p]]"));//false
System.out.println("0".matches("[a-z&&[^m-p]]"));//false
下面我们也来实操一下预定义字符吧:
- .表示任意一个字符
System.out.println("你".matches(".."));//false
System.out.println("你".matches("."));//true
System.out.println("你a".matches(".."));//true
- \d只能是任意的一位数字,简单来记:两个\表示一个\
System.out.println("a".matches("\d"));// false
System.out.println("3".matches("\d"));// true
System.out.println("333".matches("\d"));// false
System.out.println("333".matches("\d\d\d"));// true
- \w只能是一位单词字符[a-zA-z_8-9]
System.out.println("z".matches("\w"));// true
System.out.println("2".matches("\w"));// true
System.out.println("21".matches("\w"));// false
System.out.println("你".matches("\w"));//false
- 非单词字符
System.out.println("你".matches("\W"));// true
System.out.println("w".matches("\W"));// false
以上正则只能匹配校验单个字符,想要匹配多个就想需要使用下面方法:
- 必须是数字 字母下划线 至少 6位
System.out.println("2442fsfsf".matches("\w{6,}"));//true
System.out.println("244f".matches("\w{6,}"));//false
- 必须是数字和字符 必须是4位
System.out.println("-----------6-------------");
System.out.println("23dF".matches("[a-zA-Z0-9]{4}"));//true
System.out.println("23dF".matches("[\w&&[^_]]{4}"));//true
System.out.println("23_F".matches("[a-zA-Z0-9]{4}"));//false
System.out.println("23_F".matches("[\w&&[^_]]{4}"));//false
- 忽略大小写字母
- 在匹配的时候忽略abc的大小写
String regex4="(?i)abc";
System.out.println("abc".matches(regex4)); // true
System.out.println("ABc".matches(regex4)); // true
System.out.println("aBc".matches(regex4)); // true
2. 在匹配的时候忽略bc的大小写
String regex5="a(?i)bc";
System.out.println("abc".matches(regex5)); // true
System.out.println("ABc".matches(regex5)); // false
System.out.println("aBc".matches(regex5)); // true
3. 在匹配的时候忽略b的大小写
String regex6="a((?i)b)c";
System.out.println("abc".matches(regex6)); // true
System.out.println("ABc".matches(regex6)); // false
System.out.println("aBc".matches(regex6)); // true
到这里就学完啦,我们下面来做几个案例吧:
- 请编写正则表达式验证用户输入的手机号码是否满足要求。
验证手机号码 13112345678 131123456781
分成3部分:
第一部分:1 表示手机号码只能以1开头。
第二部分:[3-9] 表示手机号码第二位只能是3-9之间的。
第三部分:\d{9} 表示任意数字可以出现9次,也只能出现9次。
String regex1 = "1[3-9]\d{9}";
System.out.println("13112345678".matches(regex1));//true
System.out.println("131123456781".matches(regex1));//false
- 请编写正则表达式验证用户输入的邮箱号是否满足要求。
验证座机电话号码 020-2324242 07123242434
分成3部分:
第一部分:0 表示号码只能以0开头。\d{2,3} 表示区号从第二位开始可以是任意数字,可以出现2-3次
第二部分:- ?表示次数0次或者1次
第三部分:号码 号码第一位也不能以0开头,第二位开始可以是任意的数字,号码总长度5-10位
String regex2 = "0\d{2,3}-?[1-9]\d{4,9}";
System.out.println("020-2324242".matches(regex2));//true
System.out.println("07123242434".matches(regex2));//true
- 请编写正则表达式验证用户输入的电话号码是否满足要求
验证邮箱号码 3232323@qq.com dleieee9@pci.com.cn
分成3部分:
第一部分:@的左边 \w+ 任意的字母数字下划线至少出现一次就可以了
第二部分:@ 只能出现一次
第三部分:3.1 .的左边 [\w&&[^_]{2,6}] 任意的字母加数字总共出现6次,不能出现下划线
3.2 . \.
3.3 .的右边 大写字母和小写字母都可以,只能出现2-3次
(.[a-zA-Z]{2,3}){1,2} 我们可以把3.2和3.3看出一组,可以出现1次或者2次
String regex3 = "\w+@[\w&&[^_]]{2,6}(\.[a-zA-Z]{2,3}){1,2}";
System.out.println("3232323@qq.com".matches(regex3));//true
System.out.println("dleieee9@pci.com.cn".matches(regex3));//true
- 请编写正则表达式验证用户名是否满足要求。
要求:大小写字母,数字,下划线一共4-16位
String regex1 ="\w{4,16}";
System.out.println("zhangsan".matches(regex1)); //true
System.out.println("lisi".matches(regex1)); //true
System.out.println("$123".matches(regex1)); //false
-
请编写正则表达式验证用户身份证号码是否满足要求。
- 简单要求:18位,前17位任意数字,最后一位可以是数字可以是大写或小写的x
- 复杂要求:按照身份证号码的格式严格要求。
-
简单校验
// 简单校验
String regex2 = "[1-9]\d{16}(\d|(?i)x)";
System.out.println("41080119930228457x".matches(regex2)); //true
System.out.println("01080119930228457x".matches(regex2)); //false
- 复杂校验
//前面6位:省份,市区,派出所等信息第一位不能是8,后面5位是任意数字
//年的前半段:18 19 20
//年的后半段:任意数字出现两次
//月份: 01 ~09 10 11 .12
//日期: 81 ~ 31
//后面四位: 任意数字出现3次 最后一位可以是数字也可以是大写x或者小写x
String regex3 = "[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]";
System.out.println("41080119930228457x".matches(regex3)); //true
System.out.println("01080119930228457x".matches(regex3)); //false
下面我们来做个总结吧:
| 符号 | 含义 | 举例 |
|---|---|---|
| ? | 0次或1次 | \d? |
| * | 0次或多次 | \d* (abc)* |
| + | 1次或多次 | \d+ (abc)+ |
| {} | 具体次数 | a{7} \d{7,19} |
| (?i) | 忽略后面字符的大小写 | (?i)abc |
| a((?i)b)c | 只忽略b的大小写 | a((?i)b)c |
下面我们来看一下正则表达式在字符串方法中的使用吧:
正则表达式方法
| 方法名 | 说明 |
|---|---|
| public string[]matches(string regex) | 判断字符串是否满足正则表达式的规则 |
| public string replaceAll(string regex,string newstr) | 按照正则表达式的规则进行替换 |
| public string[] split(string regex) | 按照正则表达式的规则切割字符串 |
前面我们学习了matches方法,下面我们对剩下两个来实操一下吧:
-
先来看个例子:
有一段字符串:小诗诗dqwefqwfqwfwg12312小丹丹dqwefqwfqwfwg12312小惠惠
// 要求1:把字符串中三个姓名之间的字母替换为vs
String str = "小诗诗dqwefqwfqwfwg12312小丹丹dqwefqwfqwfwg12312小惠惠"; String result = str.replaceAll("[\w&&[^_]]+", "vs"); System.out.println(result);是不是全部成功替换为vs了呀!我们再来看第二个要求:
// 要求2:把字符串中的三个姓名切割出来
String str = "小诗诗dqwefqwfqwfwg12312小丹丹dqwefqwfqwfwg12312小惠惠"; String[] arr = str.split("[\w&&[^_]]+"); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); }怎么样,是不是全部把他们都给切割出来了呀!
正则表达式分组
分组:分组就是一个小括号。
正则表达式每组是有组号的,也就是序号。
- 规则1:从1开始,连续不间断
- 规则2:以左括号为基准,最左边的是第一组,其次第二组,以此类推。
下面我们来实操一下吧:
-
需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
- 举例: a123a b456b 17891 a123b
String regex1 = "(.).+\1"; System.out.println("a123a".matches(regex1));//true System.out.println("b456b".matches(regex1));//true System.out.println("17891".matches(regex1));//true System.out.println("a123b".matches(regex1));//false -
需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
- 举例: abc123abc b456b 123789123 abc123abd
String regex2 = "(.+).+\1"; System.out.println("abc123abc".matches(regex2));//true System.out.println("b456b".matches(regex2));//true System.out.println("123789123".matches(regex2));//true System.out.println("abc123abd".matches(regex2));//false -
需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
- 举例: aaa123aaa bbb456bbb 111789111 111789112
String regex3 = "((.)\2*).+\1"; System.out.println("aaa123aaa".matches(regex3));//true System.out.println("bbb456bbb".matches(regex3));//true System.out.println("111789111".matches(regex3));//true System.out.println("111789112".matches(regex3));//false
正则表达式捕获分组
后续还要继续使用本组的数据。
- 正则内部使用:\组号
- 正则外部使用:$组号
下面我们来看个案例:
需求:将字符串:我要学学编编编编程程程程程程。替换为:我要学编程
String str = "我要学学编编编编程程程程程程";
String result = str.replaceAll("(.)\1+", "$1");
System.out.println(result);
我们来看一下:
是不是就把重复的给去掉了呀!那这些正则表达式什么意思呢?我们来看一下:
// (.) 表示把重复内容的第一个字符看作第一组
// \1 表示第一字符再次出现
// + 至少一次
// $1 表示把正则表达式中第一组的内容,再拿出来用
正则表达式非捕获分组
分组之后不需要再用本组数据,仅仅是把数据括起来,不占组号。
| 符号 | 含义 | 举例 |
|---|---|---|
| (?:正则) | 获取所有 | Java(?:8,11,17) |
| (?=正则) | 获取前面部分 | Java(?=8,11,17) |
| (?!正则) | 获取不是指定内容的前面部分 | Java(?!8,11,17) |
好啦,正则表达式常用案例就学到这里啦,有什么不懂的可以在评论区评论,大家一起探讨哟,我们下期不见不散!!!
==最后非常感谢您的阅读,也希望能得到您的反馈 ==