java.util.regex是一个从JDK1.4开始提供的正则表达式工具包,包括两个类Pattern和Matcher Pattern,Pattern是一个正则表达式经编译后的表现模式。Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查。
Pattern
Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式。该方法接受一个正则表达式作为它的第一个参数。
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
String pattern = ".*chihai.*";
String content = "chihai is shuai bi";
boolean isMatch = Pattern.matches(pattern,content);
System.out.println(isMatch);
运行打印结果:true
从上述例子中可以看到首先通过compile工厂方法创建正则表达式匹配模式,字符中是否包含"chihai",在拿到返回的Pattern对象后使用matches方法对content字符串进行校验,结果打印为true。
public static Pattern compile(String regex, int flags) {
return new Pattern(regex, flags);
}
在创建pattern对象的时候还可以使用上面这个方法指定flag参数用来控制正则表达式的匹配行为:
- Pattern.CANON_EQ:启用规范等价。当且仅当两个字符的“正规分解(canonicaldecomposition)”都完全相同的情况下,才认定匹配。默认情况下,不考虑“规范相等性(canonical equivalence)”。
- Pattern.CASE_INSENSITIVE:启用不区分大小写的匹配。默认情况下,大小写不敏感的匹配只适用于US-ASCII字符集。这个标志能让表达式忽略大小写进行匹配,要想对Unicode字符进行大小不敏感的匹配,只要将UNICODE_CASE与这个标志合起来就行了。
- Pattern.COMMENTS:模式中允许空白和注释。在这种模式下,匹配时会忽略(正则表达式里的)空格字符(不是指表达式里的“\s”,而是指表达式里的空格,tab,回车之类)。注释从#开始,一直到这行结束。可以通过嵌入式的标志来启用Unix行模式。
- Pattern.DOTALL:启用dotall模式。在这种模式下,表达式‘.’可以匹配任意字符,包括表示一行的结束符。默认情况下,表达式‘.’不匹配行的结束符。
- Pattern.LITERAL:启用模式的字面值解析。
- Pattern.MULTILINE:启用多行模式。在这种模式下,‘^’和‘$ ’分别匹配一行的开始和结束。此外,‘^’仍然匹配字符串的开始,‘$’也匹配字符串的结束。默认情况下,这两个表达式仅仅匹配字符串的开始和结束。
- Pattern.UNICODE_CASE:启用Unicode感知的大小写折叠。在这个模式下,如果你还启用了CASE_INSENSITIVE标志,那么它会对Unicode字符进行大小写不敏感的匹配。默认情况下,大小写不敏感的匹配只适用于US-ASCII字符集。
- Pattern.UNIX_LINES: 启用Unix行模式。在这个模式下,只有‘\n’才被认作一行的中止,并且与‘.’、‘^’、以及‘$’进行匹配。
Matcher
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。上述例子中我们调用了Pattern 对象的matches方法,其实从源码中可以看到matches方法只是一个简单的整合,底层调用的还是matcher方法。Matcher类还提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持。
public static boolean matches(String regex, CharSequence input) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
return m.matches();
}
// 判断匹配结果,匹配成功返回true,否则返回false
m1.find()
// 返回匹配到的子字符串。在调用该方法前必须先调用Matcher.find()方法,否则报错 No match found。
m1.group()
捕获组:
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
1.正则中定义名为NAME的分组
(?<NAME>X)
这里X为我们要匹配的内容,注意,在这个命名不能重复,名字也不能以数字开头!
2.反向引用NAME组所匹配到的内容
\k<NAME>
注意,反向引用是针对组所匹配到的内容,而非组的表达式。
3.替换中,引用组NAME中捕获到的字符串
${NAME}
4.获取NAME组捕获的字符串
group(String NAME)
注意:也可以使用序号对命名捕获进行引用,序号从1开始,0为正则的完整匹配结果。
案例:
Pattern p = Pattern.compile("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})");
Matcher matcher = p.matcher("1996-05-10");
if (matcher.find()) {
System.out.println(matcher.group(1) + "年");
System.out.println(matcher.group(2) + "月");
System.out.println(matcher.group(3) + "日");
System.out.println(matcher.group("year") + "年");
System.out.println(matcher.group("month") + "月");
System.out.println(matcher.group("day") + "日");
}
Pattern之字符串的分割与替换:
在String类中字符串的分割与替换都是通过调用Pattern中方法进行实现的
@Test
public void test2(){
String str = "asfas5fsaf5s4fs6af.sdaf.asf.wqre.qwr.fdsf.asf.asf.asf";
//将字符串中的.替换成_,因为.是特殊字符,所以要用\.表达,又因为\是特殊字符,所以要用\\.来表达.
str = str.replaceAll("\\.", "_");
System.out.println(str);
}
同时还为我们提供了replaceFirst方法 。不同的是,replaceFirst 替换首次匹配,replaceAll 替换所有匹配。
@Test
public void test3(){
String str = "池|海";
String[] strs = str.split("\\|");
for (String s : strs){
System.out.println(s);
}
}