什么是正则?
正则就是对文本进行 匹配、查询、替换和提取字符串 的一种处理工具
1 功能介绍
- 匹配和验证: 例如对邮箱、手机号等数据的验证,快速匹配是否满足格式;
- 搜索和替换文本: 可以用正则文本中是否包含指定字符串,并可对其进行替换为其他数据;
- 数据提取 : 可以通过正则提取文本中的网址、手机号、邮箱等特定规则数据;
- 自动化处理:可用于自动化处理文本,自动生成代码,或批量文件命名等操作。
1.1 示例
使用正则进行手机号验证
private static void matchPhoneLength(){
String phone = "110";
//匹配手机号长度
boolean matches = phone.matches("\\d{11}");
System.out.println(matches);//false
String phone1 = "11111111111";
//匹配手机号长度
boolean matches1 = phone1.matches("\\d{11}");
System.out.println(matches1);//true
}2 使用
String 的 matches 提供了正则的匹配,参数为正则表达式。
2.1 匹配任意字符
. 表示匹配任意字符。
System.out.println("a1b".matches("a.b"));//true
System.out.println("abb".matches("a.b"));//true
System.out.println("a¥b".matches("a.b"));//true
System.out.println("ab".matches("a.b"));//false2.2 匹配空格
\\s 可以匹配空格字符及tab 字符( JAVA 中 tab 用 \t 表示 )。
System.out.println(" ".matches("\\s"));//true
System.out.println("\t".matches("\\s"));//true
System.out.println("a".matches("\\s"));//false2.3 模糊匹配
在 JAVA 中 \ 表示转义字符,而正则是使用 \\ 加 d,D,w,W 等表示特殊匹配;
如 \\d 表示匹配数据 0-9,\w 匹配字母、下划线及数字等,\\D 匹配非数据,\\W 匹配非字母、下划线及数字。
private static void matchNumberAndLetter(){
//匹配数字
System.out.println("1".matches("\\d"));//true
System.out.println("a".matches("\\d"));//false
//匹配字母,数字,下划线
System.out.println("a".matches("\\w"));//true
System.out.println("1".matches("\\w"));//true
System.out.println("_".matches("\\w"));//true
System.out.println(".".matches("\\w"));//false
}警告
正则中
\\d,\\W这类代码,出现一次只能匹配一次,若字符串中有多个字符,需要重复使用才能匹配所有数据如"12".matches("\\d\\d"),或使用重复匹配符。
2.4 重复匹配符
-
- : 匹配前一个字符或组 0 次或多次(即“可有可无,但可以有多个”)
-
- : 匹配前一个字符或组 1 次或多次(即“至少出现一次”)。
- ? : 匹配前一个字符或组 0 次或 1 次(即“可选的单个字符”)。
- 匹配指定次数:通过
{次数}来实现, 如果需匹配一个区间使用{次数,次数}进行匹配。
private static void matchCount(){
System.out.println("123".matches("\\d*"));//true >0
System.out.println("1ab".matches("\\d+"));//false =1
System.out.println("123".matches("\\d+"));//true
System.out.println("abc".matches("\\d?"));//false
System.out.println("12".matches("\\d?"));//false
System.out.println("123".matches("\\d{2}"));//false
System.out.println("123".matches("\\d{3}"));//true
boolean matches = phone.matches("\\d{3,4}-\\d{7,8}"); //最少匹配三位,最多匹配四位
System.out.println(matches);//true
}2.5 总结
2.5.1 单字符匹配
| 正则表达式 | 规则 | 可以匹配 |
|---|---|---|
A | 指定字符 | A |
\u548c | 指定Unicode字符 | 和 |
. | 任意字符 | a,b,&,0 |
\d | 数字0~9 | 0~9 |
\w | 大小写字母,数字和下划线 | az,AZ,0~9,_ |
\s | 空格、Tab键 | 空格,Tab |
\D | 非数字 | a,A,&,_,…… |
\W | 非\w | &,@,中,…… |
\S | 非\s | a,A,&,_,…… |
2.5.2 多字符匹配
| 正则表达式 | 规则 | 可以匹配 |
|---|---|---|
A* | 任意个数字符 | 空,A,AA,AAA,…… |
A+ | 至少1个字符 | A,AA,AAA,…… |
A? | 0个或1个字符 | 空,A |
A{3} | 指定个数字符 | AAA |
A{2,3} | 指定范围个数字符 | AA,AAA |
A{2,} | 至少n个字符 | AA,AAA,AAAA,…… |
A{0,3} | 最多n个字符 | 空,A,AA,AAA |
3 复杂匹配
3.1 匹配开头和结尾
正则对多行进行匹配时,^ 表示开头,& 表示结尾
System.out.println("a12b".matches("^a.+b$"));// true
System.out.println("aabsb".matches("^a.+b$"));// true
System.out.println("aa".matches("^a.+b$"));// false3.2 匹配指定范围
[...] 可以匹配指定范围内的字符,如匹配字符是否在 [1-3] 内。
//第二位是数字且小于5
System.out.println("a2".matches(".[0-4].*")); //true
System.out.println("a6".matches(".[0-4].*")); // false
System.out.println("a2".matches(".[01234].*")); //true
System.out.println("a6".matches(".[01234].*")); // false3.3 或规则匹配
用 | 连接的两个规则是 或 规则,AB|CD 表示既可以匹配 AB 也可以匹配 CD;
System.out.println("1".matches("1|2"));//true
System.out.println("2".matches("1|2"));//true3.4 使用括号
当想要匹配 learn java,learn php,learn go 时,规则可并行为 learn\sjava|learn\sphp|learn\sgo 也可以使用括号对规则进行优化:
learn\s(java|php|go) 提取公共部分用括号括起来。
//括号提取
String regex = "learn\\s(java|php|go)";
System.out.println("learn java".matches(regex));//true
System.out.println("learn php".matches(regex));//true
System.out.println("learn go".matches(regex));//true3.5 总结
| 正则表达式 | 规则 | 可以匹配 |
|---|---|---|
| ^ | 开头 | 字符串开头 |
| $ | 结尾 | 字符串结束 |
| [ABC] | […]内任意字符 | A,B,C |
| [A-F0-9xy] | 指定范围的字符 | A,……,F,0,……,9,x,y |
| [^A-F] | 指定范围外的任意字符 | 非A~F |
| AB|CD|EF | AB或CD或EF | AB,CD,EF |
4 分组匹配
引用
前文提到用
(...)提取子串进行匹配,实际还有一种作用,可用在分组匹配中。
4.1 例如
要将一个电话号码 012-12345678 先进行正则验证,后对子串进行拆分区号和号码。
//数据规则匹配
String str = "012-12345678";
System.out.println(str.matches("\\d{3,4}-\\d{7,8}"));//true
//分组匹配
String regex = "(\\d{3,4})-(\\d{7,8})";
Pattern compile = Pattern.compile(regex);
Matcher matcher = compile.matcher(str);
if (matcher.matches()){
System.out.println(matcher.group(1));//012
System.out.println(matcher.group(2));//12345678
System.out.println(matcher.group(0));//012-12345678
}如果要根据正则规则对文本进行分组,需先使用 (...) 将需分组的规则包围起来,然后引入 Patten 对象进行匹配。
4.2 Pattern
使用 String.matches() 方法进行多次匹配,复用率低。而使用 Pattern 对象可以反复使用实现编译一次,多次匹配。
import java.util.regex.*;
public class Main {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");
pattern.matcher("010-12345678").matches(); // true
pattern.matcher("021-123456").matches(); // false
pattern.matcher("022#1234567").matches(); // false
// 获得Matcher对象:
Matcher matcher = pattern.matcher("010-12345678");
if (matcher.matches()) {
String whole = matcher.group(0); // "010-12345678", 0表示匹配的整个字符串
String area = matcher.group(1); // "010", 1表示匹配的第1个子串
String tel = matcher.group(2); // "12345678", 2表示匹配的第2个子串
System.out.println(area);
System.out.println(tel);
}
}
}==使用 Matcher 时,必须首先调用 matches() 判断是否匹配成功,匹配成功后,才能调用 group() 提取子串。==