Java的Pattern与Matcher类
(一)java.uti
java.util 是 java 实用工具类库,该类库提供了一些实用的工具类和数据结构。举个栗子,提供了日期(Data)类、日历(Calendar)类来产生和获取日期及时间;提供了随机数(Random)类产生各种类型的随机数;还提供了堆栈(Stack)、向量(Vector) 、位集合(Bitset)以及哈希表(Hashtable)等类来表示相应的数据结构。
(二)java 正则表达式
java.util 提供了正则表达式的工具类库:java.util.regex 。
1,第一个小栗子,匹配整个字符串
Pattern.matches(正则,待匹配的字符串)
: 对整个待匹配的字符串进行匹配,只有整个字符串都匹配了才返回true。
正则 | 描述 |
---|---|
\s | 匹配空格 |
+ | 匹配1次或多次,至少匹配1次 |
\s+ | 匹配1个或多个空格,至少1个空格 |
\
:转义字符,例如"\n"匹配换行符。序列"\\"匹配"\","\("匹配"("。所以正则just\s+do\s+it\s+
需要添加转义字符,结果为just\\s+do\\s+it\\s+
。
程序及结果:
private static void firstExample(){
String pattern = "just\\s+do\\s+it\\s+";
String content1 = "just do it";
String content11 = "just do it ";
String content111 = "just do it ";
String content1111 = "Please just do it !";
boolean result1 = Pattern.matches(pattern, content1); //返回false
boolean result11 = Pattern.matches(pattern, content11); //返回true
boolean result111 = Pattern.matches(pattern, content111); //返回true
boolean result1111 = Pattern.matches(pattern, content1111); //返回false
System.out.println(result1+"-"+result11+"-"+result111+"-"+result1111); //返回false-true-true-false
}
2,第二个小栗子,匹配字符串是否包含符合正则的子字符串
pattern()
:返回正则,使用时还需要添加上转义字符。
find()
:判断匹配结果,匹配成功返回true,否则返回false
group()
:返回匹配到的子字符串。在调用该方法前必须先调用Matcher.find()方法,否则报错 No match found。
private static void secondExample(){
Pattern p0= Pattern.compile("just\\s+do\\s+it\\s+");
System.out.println(p0.pattern()); //返回 just\s+do\s+it\s+
Pattern p= Pattern.compile("\\d+");
Matcher m1=p.matcher("5,55 are good numbers,666");
System.out.println(m1.find()); //返回true
System.out.println(m1.group()); //返回5
System.out.println(m1.group()); //返回5
}
group()返回第一次匹配到的子字符串,要通过遍历才能返回每次匹配到的子字符串:
private static void thirdExample(){
Pattern p= Pattern.compile("\\d+");
Matcher m1=p.matcher("5,55 are good numbers,666");
while(m1.find()) {
// System.out.println(m1.group(0)); 这种写法也可以
System.out.println(m1.group()); //返回5 55 666
}
}
3,第三个小栗子:matcher.group(int group); 与 matcher.groupCount();
matcher.group(int group); 与 matcher.groupCount();
是用在pattern中有‘()’时使用。
如下栗子,整个完整的正则是"(\d+)([\sa-z]+)",该正则又由两个子正则"(\d+)"和"([\sa-z]+)"组成。
- groupCount()表示子正则的个数
- group(0)表示完整正则的匹配结果。
- 第一组子正则"(\d+)"用于匹配数字,匹配结果为group(1);
- 第二组子正则"([\sa-z]+)"用于匹配空格和小写字母的组合,匹配结果为group(2)。
代码和运行结果如下:
private static void fouthExample(){
Matcher matcher = Pattern.compile("(\\d+)([\\sa-z]+)").matcher("666 is greate number");
matcher.find(); // 此方法不可省略 System.out.println(matcher.groupCount()); //2
System.out.println(matcher.group(0)); // "666 is greate number"
System.out.println(matcher.group(1)); // "666"
System.out.println(matcher.group(2)); // " is greate number"
// System.out.println(matcher.group(3)); // IndexOutOfBoundsException
}
如果正则表达式中没有'()',那么就是匹配整个正则,所以匹配结果可以写成group(0)
,即第二个栗子中System.out.println(m1.group());
也可以写成System.out.println(m1.group(0));
4,java.util.regex 核心的三个类讲解
1)Pattern 类
Pattern 类没有公共构造方法,所以我们不能通过new Pattern()方式创建Pattern 对象。但是我们可以调用其公共静态编译方法compile来创建对象,就如上面栗子中那样写的一般。
compile方法源码:
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
继续查看new Pattern(regex, 0);的源码:
private Pattern(String p, int f) {
...
}
因此,Pattern 类的构造方法是private的,外部无法直接调用。而该构造方法对内部可见,所以通过public的compile方法去间接调用该构造方法创建Pattern对象。这点原理与类成员属性设置为private级别,同时暴露出getter、setter方法的通道让外部可以访问类成员属性是一样的。
2)Matcher 类
Matcher 对象作用是对输入字符串进行正则匹配。Matcher 也没有公共构造方法,需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
3)PatternSyntaxException 类
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
(三)java 强制性异常和非强制性异常
java中的异常分为两大类:
- 强制性异常
必须try catch 或者throws处理的异常。 - 非强制性异常
可以try catch或者thows处理的异常,也可以不做异常处理。所以我们在上面的栗子中可以不对PatternSyntaxException进行异常处理。
java中除了RuntimeException外,都是强制性异常。
(四)栗子完整代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternAndMatcher {
public static void main(String[] args){
// firstExample();
// secondExample();
thirdExample();
}
private static void firstExample(){
String pattern = "just\\s+do\\s+it\\s+";
String content1 = "just do it";
String content11 = "just do it ";
String content111 = "just do it ";
String content1111 = "Please just do it !";
boolean result1 = Pattern.matches(pattern, content1); //返回false
boolean result11 = Pattern.matches(pattern, content11); //返回true
boolean result111 = Pattern.matches(pattern, content111); //返回true
boolean result1111 = Pattern.matches(pattern, content1111); //返回false
System.out.println(result1+"-"+result11+"-"+result111+"-"+result1111); //返回false-true-true-false
}
private static void secondExample(){
Pattern p0= Pattern.compile("just\\s+do\\s+it\\s+");
System.out.println(p0.pattern()); //返回 just\s+do\s+it\s+
Pattern p= Pattern.compile("\\d+");
Matcher m1=p.matcher("5,55 are good numbers,666");
System.out.println(m1.find()); //返回true
System.out.println(m1.group()); //返回5
System.out.println(m1.group()); //返回5
}
private static void thirdExample(){
Pattern p= Pattern.compile("\\d+");
Matcher m1=p.matcher("5,55 are good numbers,666");
while(m1.find()) {
System.out.println(m1.group()); //返回5 55 666
}
}
private static void fouthExample(){
Matcher matcher = Pattern.compile("(\\d+)([\\sa-z]+)").matcher("666 is greate number");
matcher.find(); // 此方法不可省略
System.out.println(matcher.groupCount()); //2
System.out.println(matcher.group(0)); // "666 is greate number"
System.out.println(matcher.group(1)); // "666"
System.out.println(matcher.group(2)); // " is greate number"
// System.out.println(matcher.group(3)); // IndexOutOfBoundsException
}
}