Java Pattern类和Matcher类的详细介绍
1、Pattern类和Matcher类简介
Pattern 对象是正则表达式编译后在内存中的表示形式,因此,正则表达式字符串必须先被编译为 Pattern 对象,然后再利用该 Pattern 对象创建对应的 Matcher 对象。匹配结果保留在 Matcher 对象中,多个 Matcher 对象可共享同一个 Pattern 对象。下面我们就来看看Pattern类和Matcher类的详细介绍,希望对大家有所帮助。
2、Pattern 类的常用方法
Pattern 类的常用方法,如下所示:
// 将一个字符串编译成 Pattern 对象
Pattern p = Pattern.compile("a*c");
// 使用 Pattern 对象创建 Matcher 对象
Matcher m = p.matcher("abc");
// 返回 true
boolean result = m.matches();
上面定义的 Pattern 对象可以多次重复使用。如果某个正则表达式仅需一次使用,则可直接使用 Pattern 类的静态 matches()
方法,此方法自动把指定字符串编译成匿名的 Pattern 对象,并执行匹配,代码如下所示:
// 返回 true
boolean result = Pattern.matches ("a*c","abc");
2、Matcher 类的常用方法
名称 | 说明 |
---|---|
find() | 返回目标字符串中是否包含与 Pattern 匹配的子串 |
group() | 返回上一次与 Pattern 匹配的子串 |
start() | 返回上一次与 Pattern 匹配的子串在目标字符串中的开始位置 |
end() | 返回上一次与 Pattern 匹配的子串在目标字符串中的结束位置加 1 |
lookingAt() | 返回目标字符串前面部分与 Pattern 是否匹配 |
matches() | 返回整个目标字符串与 Pattern 是否匹配 |
reset() | 将现有的 Matcher 对象应用于一个新的字符序列。 |
2.1、find()和 group()方法
通过 Matcher 类的 find()
和 group()
方法可以从目标字符串中依次取出特定子串(匹配正则表达式的子串),例如互联网的网络爬虫,它们可以自动从网页中识别出所有的电话号码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test
{
public static void main(String[] args)
{
// 使用字符串模拟从网络上得到的网页源码
String str = "出售JAVA教程,联系电话:13600000001" + "毕业代做,联系电话:13600000002" + "出售二手电脑,联系电话:15800000001";
// 创建一个Pattern对象,并用它建立一个Matcher对象
// 该正则表达式只抓取13X和15X段的手机号
// 实际要抓取哪些电话号码,只要修改正则表达式即可
Matcher m = Pattern.compile("((13\\d)|(15\\d))\\d{8}").matcher(str);
// 将所有符合正则表达式的子串(电话号码)全部输出
while (m.find())
{
System.out.println(m.group());
}
}
}
从上面运行结果可以看出,find()
方法依次查找字符串中与 Pattern 匹配的子串,一旦找到对应的子串,下次调用 find()
方法时将接着向下查找。
2.2、start()和 end()方法
find()
方法还可以传入一个 int 类型的参数,带 int 参数的 find()
方法将从该 int 索引处向下搜索。start()
和 end()
方法主要用于确定子串在目标字符串中的位置,如下程序所示。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test2
{
public static void main(String[] args)
{
// 创建一个Pattern对象,并用它建立一个Matcher对象
String regStr = "Java is very easy!";
System.out.println("目标字符串是:" + regStr);
Matcher m = Pattern.compile("\\w+").matcher(regStr);
while (m.find())
{
System.out.println(m.group() + "子串的起始位置:" + m.start() + ",其结束位置:" + m.end());
}
}
}
上面程序使用 find()
、group()
方法逐项取出目标字符串中与指定正则表达式匹配的子串,并使用start()
、end()
方法返回子串在目标字符串中的位置。运行上面程序,看到如下运行结果:
目标字符串是:Java is very easy!
Java子串的起始位置:0,其结束位置:4
is子串的起始位置:5,其结束位置:7
very子串的起始位置:8,其结束位置:12
easy子串的起始位置:13,其结束位置:17
2.3、matches() 和 lookingAt() 方法
matches()
和 lookingAt()
方法有点相似,只是 matches()
方法要求整个字符串和 Pattern 完全匹配时才返回 true
,而 lookingAt()
只要字符串以 Pattern 开头就会返回 true
。reset()
方法可将现有的 Matcher 对象应用于新的字符序列:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test3
{
public static void main(String[] args)
{
String[] mails =
{ "mymail@163.com", "mymail@gmail.com", "mymail@myweb.org", "mymail@abc.xx" };
String mailRegEx = "\\w{3,20}@\\w+\\.(com|org|cn|net|gov)";
Pattern mailPattern = Pattern.compile(mailRegEx);
Matcher matcher = null;
for (String mail : mails)
{
if (matcher == null)
{
matcher = mailPattern.matcher(mail);
}
else
{
matcher.reset(mail);
}
String result = mail + (matcher.matches() ? "是" : "不是") + "一个有效的邮件地址!";
System.out.println(result);
}
}
}
上面程序创建了一个邮件地址的 Pattern,接着用这个 Pattern 与多个邮件地址进行匹配。当程序中的 Matcher 为 null
时,程序调用 matcher()
方法来创建一个 Matcher 对象,一旦 Matcher 对象被创建,程序就调用 Matcher 的 reset()
方法将该 Matcher 应用于新的字符序列。
从某个角度来看,Matcher 的 matches()
、lookingAt()
和 String 类的 equals()
有点相似。区别是 String 类的 equals()
都是与字符串进行比较,而 Matcher 的 matches()
和 lookingAt()
则是与正则表达式进行匹配。
事实上,String 类里也提供了 matches()
方法,该方法返回该字符串是否匹配指定的正则表达式。例如:
"mymail@163.com".matches("\\w{3,20}@\\w+\\.(com|org|cn|net|gov)"); // 返回 true
2.4、小结
在Matcher类中,matches()
是必须全部匹配;lookingAt()
匹配的字符必须要在字符串的最前面;find()
匹配的字符可以在字符串的任意的地方。
start()
、end()
、group()
这三个方法必须是在有字符匹配到的条件下才能够调用,否则会报错。start()
返回匹配到的子字符串在字符串中的索引位置,end()
返回匹配到的子字符串的最后一个字符在字符串中的索引位置,group()
返回匹配到的子字符串。另外,start()
、end()
、group()
均有一个重载方法它们是start(int i)
、end(int i)
、group(int i)
专用于分组操作。最后,Mathcer类还有一个groupCount()
用于返回有多少组。