Java Pattern类和Matcher类的使用

1年前 (2024-04-27)
java.util.regex 是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类:Pattern 和 Matcher。

Pattern 对象是正则表达式编译后在内存中的表示形式,因此,正则表达式字符串必须先被编译为 Pattern 对象,然后再利用该 Pattern 对象创建对应的 Matcher 对象。执行匹配所涉及的状态保留在 Matcher 对象中,多个 Matcher 对象可共享同一个 Pattern 对象。

因此,典型的调用顺序如下:

// 将一个字符串编译成 Pattern 对象
Pattern p = Patter网站站点" rel="nofollow" />

boolean b = Pattern.matches ("a*b","aaaaab");    // 返回 true

上面语句等效于前面的三条语句。但采用这种语句每次都需要重新编译新的 Pattern 对象,不能重复利用已编译的 Pattern 对象,所以效率不高。Pattern 是不可变类,可供多个并发线程安全使用。

Matcher 类提供了几个常用方法,如表 1 所示。

表 1 Matcher 类的几个常用方法

名称

说明

find()

返回目标字符串中是否包含与 Pattern 匹配的子串

group()

返回上一次与 Pattern 匹配的子串

start()

返回上一次与 Pattern 匹配的子串在目标字符串中的开始位置

end()

返回上一次与 Pattern 匹配的子串在目标字符串中的结束位置加 1

lookingAt()

返回目标字符串前面部分与 Pattern 是否匹配

matches()

返回整个目标字符串与 Pattern 是否匹配

reset()

将现有的 Matcher 对象应用于一个新的字符序列。


在 Pattern、Matcher 类的介绍中经常会看到一个 CharSequence 接口,该接口代表一个字符序列,其中 CharBuffer、String、StringBuffer、StringBuilder 都是它的实现类。简单地说,CharSequence 代表一个各种表示形式的字符串。

通过 Matcher 类的 find() 和 group() 方法可以从目标字符串中依次取出特定子串(匹配正则表达式的子串),例如互联网的网络爬虫,它们可以自动从网页中识别出所有的电话号码。下面程序示范了如何从大段的字符串中找出电话号码。

public class FindGroup {

public static void main(String[] args) {

// 使用字符串模拟从网络上得到的网页源码

String str = "我想找一套适自己的JAVA教程,尽快联系我" + "交朋友,电话号码是" + "出售二手电脑,联系方式";

// 创建一个Pattern对象,并用它建立一个Matcher对象

// 该正则表达式只抓取13X和15X段的手机号

// 实际要抓取哪些电话号码,只要修改正则表达式即可

Matcher m = Patter网站站点" rel="nofollow" />

从上面运行结果可以看出,find() 方法依次查找字符串中与 Pattern 匹配的子串,一旦找到对应的子串,下次调用 find() 方法时将接着向下查找。

提示:通过程序运行结果可以看出,使用正则表达式可以提取网页上的电话号码,也可以提取邮件地址等信息。如果程序再进一步,可以从网页上提取超链接信息,再根据超链接打开其他网页,然后在其他网页上重复这个过程就可以实现简单的网络爬虫了。

find() 方法还可以传入一个 int 类型的参数,带 int 参数的 find() 方法将从该 int 索引处向下搜索。start() 和 end() 方法主要用于确定子串在目标字符串中的位置,如下程序所示。

public class StartEnd {

public static void main(String[] args) {

// 创建一个Pattern对象,并用它建立一个Matcher对象

String regStr = "Java is very easy!";

System.out.println("目标字符串是:" + regStr);

Matcher m = Patter网站站点" rel="nofollow" /> 目标字符串是:Java is very easy!
Java子串的起始位置:0,其结束位置:4
is子串的起始位置:5,其结束位置:7
very子串的起始位置:8,其结束位置:12

easy子串的起始位置:13,其结束位置:17

matches() 和 lookingAt() 方法有点相似,只是 matches() 方法要求整个字符串和 Pattern 完全匹配时才返回 true,而 lookingAt() 只要字符串以 Pattern 开头就会返回 true。reset() 方法可将现有的 Matcher 对象应用于新的字符序列。看如下例子程序。

public class MatchesTest {

public static void main(String[] args) {

String[] mails = { "kongyeeku@16网站站点" rel="nofollow" />

"kongyeeku@16网站站点" rel="nofollow" />

public class ReplaceTest {

public static void main(String[] args) {

String[] msgs = { "Java has regular expressions in 1.4", "regular expressions now expressing in Java",

"Java represses oracular expressions" };

Pattern p = Patter网站站点" rel="nofollow" />

public class StringReg {

public static void main(String[] args) {

String[] msgs = { "Java has regular expressions in 1.4", "regular expressions now expressing in Java",

"Java represses oracular expressions" };

for (String msg : msgs) {

System.out.println(msg.replaceFirst("re\\w*", "哈哈:)"));

System.out.println(Arrays.toString(msg.split(" ")));

}

}

}

上面程序只使用 String 类的 replaceFirst() 和 split() 方法对目标字符串进行了一次替换和分割。运行上面程序,会看到如下所示的输出结果。

Java has 哈哈:) expressions in 1.4
[Java, has, regular, expressions, in, 1.4]
哈哈:) expressions now expressing in Java
[regular, expressions, now, expressing, in, Java]
Java 哈哈:) oracular expressions

[Java, represses, oracular, expressions]

正则表达式是一个功能非常灵活的文本处理工具,增加了正则表达式支持后的 Java,可以不再使用 StringTokenizer 类(也是一个处理字符串的工具,但功能远不如正则表达式强大)即可进行复杂的字符串处理。