正则表达式03
5.6正则表达式三个常用类
java.util.regex 包主要包括以下三个类:Pattern类、Matcher类和PatternSyntaxException类
-
Pattern类
Pattern对象是一个正则表达式对象。Pattern类没有公共构造方法,要创建一个Pattern对象,调用其公共静态方法,它返回一个Pattern对象。该方法接收一个正则表达式作为它的第一个参数,比如:
Pattern r = Pattern.compile(pattern);
-
Matcher类
Matcher对象是对输入字符串进行解释和匹配的引擎。与Pattern类一样,Matcher类也没有公共构造方法。需要调用Pattern对象的matcher方法来获得一个Matcher对象
-
PatternSyntaxException类
PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
5.6.1Pattern类
JAVA正则表达式, matcher.find()和 matcher.matches()的区别
- find()方法是部分匹配,是查找输入串中与模式匹配的子串,如果该匹配的串有组还可以使用group()函数
- matches()是全部匹配,是将整个输入串与模式匹配,如果要验证一个输入的数据是否为数字类型或其他类型,一般要用matches()
package li.regexp;
import java.util.regex.Pattern;
//演示matcher方法,用于整体匹配(注意是整个文本的匹配),在验证输入的字符串是否满足条件使用
public class PatternMethod {
public static void main(String[] args) {
String content="hello abc hello,侬好";
//String regStr="hello";//false
String regStr="hello.*";//true
boolean matches = Pattern.matches(regStr, content);
System.out.println("整体匹配="+matches);
}
}
matches方法的底层源码:
public static boolean matches(String regex, CharSequence input) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
return m.matches();
}
可以看到,底层还是创建了一个正则表达式对象,以及使用matcher方法,最后调用matcher类的matches方法(该方法才是真正用来匹配的)
5.6.2Matcher类
package li.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//Matcher类的常用方法
public class MatcherMethod {
public static void main(String[] args) {
String content = "hello edu jack tom hello smith hello";
String reStr = "hello";
Pattern pattern = Pattern.compile(reStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("====================");
System.out.println(matcher.start());
System.out.println(matcher.end());
System.out.println("找到:" + content.substring(matcher.start(), matcher.end()));
}
//整体匹配方法,常用于校验某个字符串是否满足某个规则
//Pattern的matches方法底层调用的就是Matcher类的matches方法
System.out.println("整体匹配=" + matcher.matches());//false
content = "hello edu jack hspedutom hello smith hello hspedu hspedu";
//如果content有字符串 hspedu,就将其替换为 小猫咪
reStr = "hspedu";
pattern = Pattern.compile(reStr);
matcher = pattern.matcher(content);
//注意:返回的字符串newStringContent才是替换后的字符,原来的字符串content是不变化的
String newStringContent = matcher.replaceAll("小猫咪");
System.out.println("newStringContent= " + newStringContent);
System.out.println("content= " + content);
}
}
5.7反向引用
请看下面的问题:
给定一段文本,请找出所有四个数字连在一起的子串,并且这四个数字要满足:
- 第一位与第四位相同
- 第二位与第三位相同
在解决前面的问题之前,我们需要了解正则表达式的几个概念:
-
分组
我们可以用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部分我们可以看作是一个子表达式/分组
-
捕获
把正则表达式中的 子表达式/分组 匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。组0代表的是整个正则式
-详见5.4.6
-
反向引用
圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用使用\\\分组号,外部反向引用使用$分组号
5.7.1反向引用的匹配原理
捕获组(Expression)在匹配成功时,会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用方式,引用这个局部变量的值。一个捕获组(Expression)在匹配成功之前,它的内容可以是不确定的,一旦匹配成功,它的内容就确定了,反向引用的内容也就是确定的了。
反向引用必然要与捕获组一同使用的,如果没有捕获组,而使用了反向引用的语法,不同语言的处理方式不一致,有的语言会抛异常,