从匹配的字符串中提取子串—— 例如从 0123-12345678中分别提取区号``电话号。
public class Main {public static void main(String[] args) {String re = "^(\\d{3,4})\\-(\\d{7,8})";Pattern p = Pattern.compile(re);Matcher m = matcher("010-12345678");if(m.matches()) {String g1 = m.group(1);String g2 = m.group(2);System.out.println(g1);System.out.println(g2);}}}
提取子串时,没办法用String.matches()这样简单的判断方法了,必须引入java.util.regex包,用Pattern对象匹配,匹配后获得一个Matcher对象,如果匹配成功,就可以直接从Matcher.group(index)返回子串。**Matcher.group(index)**参数用1表示第一个子串,2表示第二个子串,0表示正则匹配到的字符串。
Pattern
我们在前面的代码中用到的正则表达式是String.matches()方法,而在分组提取的代码用的java.util.regex包里面的Pattern和Matcher类。实际上这两种代码本质上是一样的。因为String.matches()方法内部调用 的就是pattern和Matcher类的方法。
但是反复使用String.matches()对同一个正则表达式进行多次匹配效率较低,因为每次都会创建出一样的Pattern对象。完全可以先创建聘个Pattern对象,然后反复使用,就可以实现编译一次,多次匹配。
public class Main {public static void main(String[] args) {Pattern pattern = Patter.compile("^(\\d{3,4})\\-(\\d{7,8})$");pattern.matcher("010-12345678").matches();pattern.matcher("021-123456").matches();//获得Matcher对象Matcher matcher = pattern.matcher("010-12345678");if(matcher.matches()) {String whole = matcher.group(0);//整个字符串String area = matcher.group(1);//第一个子串 区号 010String tel = matcher.group(2);//第二个子串 12345678System.out.println(tel);}}}
使用**Matcher**时,必须首先调用**matches()**判断是否匹配成功,匹配成功后,才能调用**group()**提取子串。
练习
public class Main {public static void main(String[] args) {if (s == null || s.isEmpty()) { throw new IllegalArgumentException();}String re = "^([0-2]\\d)\\:([0-5]\\d)\\:([0-5]\\d)";Pattern pattern = Pattern.compile(re);Matcher matcher = pattern.matcher(s);System.out.println(matcher.matches());if(matcher.matches()) {int hour = Integer.parseInt(matcher.group(1));if(hour >= 24) throw new IllegalArgumentException();int minutes = Integer.parseInt(matcher.group(2));int seconds = Integer.parseInt(matcher.group(3));return new int[] {hour,minutes, seconds};}throw new IllegalArgumentException();}}
