0
点赞
收藏
分享

微信扫一扫

Java分组匹配

我们前面讲到的​​(...)​​​可以用来把一个子规则括起来,这样写​​learn\s(java|php|go)​​就可以更方便地匹配长字符串了。

实际上​​(...)​​还有一个重要作用,就是分组匹配。

我们来看一下如何用正则匹配​​区号-电话号​​码这个规则。利用前面讲到的匹配规则,写出来很容易:

\d{3,4}\-\d{6,8}

虽然这个正则匹配规则很简单,但是往往匹配成功后,下一步是提取区号和电话号码,分别存入数据库。于是问题来了:如何提取匹配的子串?

当然可以用​​String​​提供的​​indexOf()​​和​​substring()​​这些方法,但它们从正则匹配的字符串中提取子串没有通用性,下一次要提取​​learn\s(java|php)​​还得改代码。

正确的方法是用​​(...)​​先把要提取的规则分组,把上述正则表达式变为​​(\d{3,4})\-(\d{6,8})​​。

现在问题又来了:匹配后,如何按括号提取子串?

现在我们没办法用​​String.matches()​​这样简单的判断方法了,必须引入​​java.util.regex​​包,用​​Pattern​​对象匹配,匹配后获得一个​​Matcher​​对象,如果匹配成功,就可以直接从​​Matcher.group(index)​​返回子串:

import java.util.regex.*;

 Run

运行上述代码,会得到两个匹配上的子串​​010​​和​​12345678​​。

要特别注意,​​Matcher.group(index)​​方法的参数用1表示第一个子串,2表示第二个子串。如果我们传入0会得到什么呢?答案是​​010-12345678​​,即整个正则匹配到的字符串。

Pattern

我们在前面的代码中用到的正则表达式代码是​​String.matches()​​方法,而我们在分组提取的代码中用的是​​java.util.regex​​包里面的​​Pattern​​类和​​Matcher​​类。实际上这两种代码本质上是一样的,因为​​String.matches()​​方法内部调用的就是​​Pattern​​和​​Matcher​​类的方法。

但是反复使用​​String.matches()​​对同一个正则表达式进行多次匹配效率较低,因为每次都会创建出一样的​​Pattern​​对象。完全可以先创建出一个​​Pattern​​对象,然后反复使用,就可以实现编译一次,多次匹配:

import java.util.regex.*;

 Run

使用​​Matcher​​时,必须首先调用​​matches()​​判断是否匹配成功,匹配成功后,才能调用​​group()​​提取子串。

利用提取子串的功能,我们轻松获得了区号和号码两部分。

利用分组匹配,从字符串​​"23:01:59"​​提取时、分、秒。


正则表达式用​​(...)​​分组可以通过​​Matcher​​对象快速提取子串:

  • ​group(0)​​表示匹配的整个字符串;
  • ​group(1)​​表示第1个子串,​​group(2)​​表示第2个子串,以此类推。
举报

相关推荐

0 条评论