廖雪峰Java9正则表达式-2正则表达式进阶-3分组匹配

1.使用括号可以提取字符串

不加括号匹配电话号码

匹配成功后,如何提取想要的字符串?
使用(...)可以分组:"^(\d{3,4})\-(\d{6,8})$"

2.String.matcher vs Pattern.matcher

前面用到的正则表达式是使用String.matches(),而我们在分组时用到的是java.util.regex.Matcher和java.util.regex.Pattern。而String.matches()内部就是调用的Matcher和Pattern类的方法。
反复使用一个正则表达式字符串进行快速匹配效率较低:

  • 正则表达式虽然是一个字符串,但首先要编译为Pattern对象 ,然后再进行匹配。因此可以先创建Pattern对象,然后反复使用
    public static void main(String[] args){
        //使用String.matches匹配
        String regex = "^\\d{3,4}\\-\\d{6,8}";
        System.out.println("使用String.matches进行匹配:"+"010-123456789".matches(regex));
        //使用Pattern类定义正则表达式
        Pattern pattern = Pattern.compile("^(\\d{3,4})\\-(\\d{6,8})$");
        //使用Pattern的matches匹配
        System.out.println("使用Pattern.matches进行匹配:"+pattern.matcher("010-12345678").matches());
        //获取matcher对象,在获取匹配结果
        Matcher matcher = pattern.matcher("010-12345678");
        System.out.println("转换为Matcher对象进行匹配:"+matcher.matches());

    }

3.使用Matcher.group(n)可以快速提取字串

    public static void main(String[] args) throws IllegalAccessException {
        Pattern pattern = Pattern.compile("^(\\d{3,4})\\-(\\d{6,8})$");
        //获取matcher对象
        Matcher matcher = pattern.matcher("010-1234567");
        //必须匹配成功,才能提取子串,即matcher.matches()不能省略,否则会报java.lang.IllegalStateException,
        try{
            System.out.println(matcher.group(0));
        }catch (Exception e){
            System.out.println(e.getClass()+": "+e.getMessage());
        }
        //因此可以改写为
        if (matcher.matches()) {
            System.out.println(matcher.group(0));
            System.out.println(matcher.group(1));
            System.out.println(matcher.group(2));
        }
    }
## 4.示例 Tel.java ```#java package com.testList;

import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Tel {
//Pattern对象是可以反复使用的
static Pattern p = Pattern.compile("^(0\d{2,3})\-([1-9]\d{5,7})$");
public static Tel parse(String s){//返回类型为Tel,同public boolean 方法名(){}
Matcher m = p.matcher(s);
if(m.matches()){
String s1 = m.group(1);
String s2 = m.group(2);
return new Tel(s1,s2);
}
return null;
}
private final String areaCode;
private final String phone;
public Tel(String areaCode, String phone){
this.areaCode = areaCode;
this.phone = phone;
}
public String getAreaCode(){
return areaCode;
}
public String getPhone(){
return phone;
}
@Override
public boolean equals(Object o){
if(o==this){
return true;
}
if( o instanceof Tel){
Tel t = (Tel) o;
return Objects.equals(t.areaCode,this.areaCode) && Objects.equals(t.phone,this.phone);
}
return false;
}
@Override
public int hashCode(){
return Objects.hash(this.areaCode,this.phone);
}
@Override
public String toString(){
return this.areaCode + "-" + this.phone;
}
}

TelTest.java
```#java
package com.testList;

import org.junit.Test;

import static org.junit.Assert.*;

public class TelTest {

    @Test
    public void testIsVaildTes() {
        assertEquals(new Tel("010","123456"),Tel.parse("010-123456"));
        assertEquals(new Tel("010","12345678"),Tel.parse("010-12345678"));

        assertNull(Tel.parse("123-12345678"));
        assertNull(Tel.parse("010-0123456"));
        assertNull(Tel.parse("010#12345678"));
    }
}

5.总结:

正则表达式分组可以通过Matcher对象快速提取字串:

  • group(0)表示匹配的整个字符串
  • group(1)表示第1个子串
  • group(2)表示第2个子串
  • ...
posted on 2019-04-23 08:49  singleSpace  阅读(1420)  评论(0编辑  收藏  举报