正则表达式在处理字符串时非常有用,本篇博客来讨论一下java中正则表达式的用法。
在java.util.regex
包下面有两个类,分别是Pattern
和Matcher
,前者表示一个正则表达式的模式,后者用来表示pattern与某个字符串的匹配信息。
Pattern
类本身没有定义构造方法,可以通过Pattern.compile()
静态方法来生成一个Pattern
对象,而Matcher
对象则是通过Pattern
对象的matcher
方法生成的。
来看一个简单的例子
String str1 = "http://www.mysite.com/category/231";
Pattern pattern = Pattern.compile("^https?://.*$");
Matcher matcher = pattern.matcher(str1);
System.out.println("str1 is match with pattern ? " + matcher.matches());
第二行通过Pattern.compile()
方法产生了一个Pattern
对象,第三行通过pattern.matcher()
产生了一个Matcher
对象。
如果一个pattern能够匹配整个字符串,则Matcher
对象的matches()
返回true,否则返回false。如果想要匹配一个字符串的一部分,需要使用Matcher
对象的find()
方法,下面会用到。
除了判断一个Pattern是否能够匹配一个字符串以外,正则表达式还可以用来精确地提取字符串中某个位置的信息,来看个例子
String str1 = "http://www.mysite.com/category/231";
Pattern pattern = Pattern.compile("^https?://(?w{3}\\.\\w+\\.(com)|(cn)|(net))/category/(?\\w+)$" );
Matcher matcher = pattern.matcher(str1);
if (matcher.matches()) {
String site = matcher.group("site");
String category = matcher.group("cat");
System.out.println("site = " + site);
System.out.println("cat = " + category);
}
上面代码的输出结果是
site = www.mysite.com
cat = 231
需要说明的是(?
的语法是正则中的捕获(capturing),通过matcher.group("groupName")
的方式可以获取到当前括号内的正则所匹配到的文本。如果?
省略了(仅使用圆括号),可以使用matcher.group(index)
的方式获取捕获到的内容。我个人倾向于使用named-capturing,因为更加精确。
再来看一个多次匹配的例子
String str2 = "java se;java ee;java fx;";
Pattern pattern2 = Pattern.compile("java\\s(?\\w+?);" );
Matcher matcher2 = pattern2.matcher(str2);
while (matcher2.find()) {
int start = matcher2.start();
int end = matcher2.end();
String append = matcher2.group("append");
String content = matcher2.group(0);
String msg = MessageFormat.format("find from {0} to {1},the content is [{2}],the append is [{3}]",
start, end, content, append);
System.out.println(msg);
}
上面代码的输出结果是
find from 0 to 8,the content is [java se;],the append is [se]
find from 8 to 16,the content is [java ee;],the append is [ee]
find from 16 to 24,the content is [java fx;],the append is [fx]
find()
方法匹配字符串中的一部分,如果能够匹配,则记录当前匹配的位置并返回true,再次调用find()
时,会从上次记录的位置之后开始匹配,所以它可以多次调用,直到它返回false为止。每次find成功后,通过Matcher
对象的start()
和end()
方法获得本次匹配的起始位置,通过group(0)
来获取匹配到的完整内容(也可以通过字符串的subString()
方法)。named-capturing的方式matcher2.group("append")
永远都能正确地获取到你需要的内容,基于索引的group方法在这种情况下就有点奇怪了,因为matcher2.group("append")
的结果与matcher2.group(1)
的结果相同,但我们的正则表达式仅仅包含一个捕获。
除了上面使用的方法以外,还有两种更加方便的方式来使用正则表达式
String str1 = "http://www.mysite.com/category/231";
Pattern.matches("^https?://.*$",str1); //true
str1.matches("^https?://.*$"); //true
第一个是Pattern
类的静态方法,第二个String
对象的方法。这两种方法都是仅当正则表达式匹配整个字符串时才返回true。