java正则表达式及api_详解Java正则表达式(中篇)

本篇将继续介绍Java正则表达式的内容, 相关组件以及API方法。

相关组件与API

在Java中,与正则有关的组件有两个:

1. Pattern

1) public static Pattern compile(String regex)

比较常用的静态方法,返回一个Pattern对象

2) public static Pattern compile(String regex, int flags)

flags 表示不同的匹配模式,默认情况下为0, 表示最常用的UNICODE模式

3) public Matcher matcher(CharSequence input)

根据输入内容,返回Mathcer对象

4) public static boolean matches(String regex, CharSequence input)

比较输入的正则regex 和 字符串 input 是否匹配,匹配返回true,不匹配返回false

5) public String[] split(CharSequence input, int limit)

limit的值,可以是正数n, 表示最后可以切割n-1次,剩余的部分全部归为数组的最后一项; 可以是0, 表示可切割无数次,但是如果切割的内容为空字符串,那么自动舍弃; 可以是负数, 表示切割无数次,但是不舍弃空字符串。

6) public String[] split(CharSequence input)

根据当前正则,切割输入的字符串, 默认limit为0。

说明:

最常用的就是静态方法 public static Pattern compile(String regex) 返回一个Pattern对象,然后调用public Matcher matcher(CharSequence input)方法,返回Matcher对象

2. Matcher

1) public boolean find()

从字符串开头向前匹配,直到匹配不符合停止,不管是部分匹配还是全部匹配,都返回true,如果匹配到字符串结束,依然没有匹配当前正则,那么返回false

2) public String group()

这个方法必须和find方法配合使用,单独使用就会报错,返回上一个find方法匹配到的内容。

3) public boolean matches()

当前正则是否匹配字符串整体, 匹配返回true, 不匹配返回false

4) public String group(int group)

这个方法和正则分组有关系,详细内容将在下一小节正则分组中详细描述。

5) public int groupCount()

返回上一次匹配中,分成了几个组

6) public Matcher reset(CharSequence input)

根据输入字符串,重新生成一个Matcher对象

7) public Matcher reset()

重置指针,从头开始匹配。

8) public Matcher region(int start, int end)

指定头尾指针的位置,重置指针。只匹配指定范围内的字符串。

9) public int start()

返回头指针的位置

10) public int start(int group)

这个方法和上面那个重载方法,意义完全不同。 这个是返回 指定的分组,在上一次匹配操作后的头指针位置。

11) public int end()

返回上一次匹配的尾指针位置。

12) public int end(int group)

返回 指定的分组,在上一次匹配操作后的尾指针位置

13) public String replaceFirst(String replacement)

替换第一个匹配到的内容

14) public String replaceAll(String replacement)

替换全部匹配的内容

数据结构说明与正则分组

数据结构

上面介绍Matcher的API,很多方法看得人迷迷糊糊,什么头指针,尾指针,上一次匹配,这些都是什么意思? 为了说明这个问题,需要通过数据结构画图来说明白:

String s = "abc123def456";

String regular = "\\w{3}";

Matcher m = Pattern.compile(regular).matcher(s);

while(m.find()) {

System.out.println("start: " + m.start());

System.out.println("end: " + m.end());

}

字符串结构如下:图1

一旦Matcher对象建好,那么就会自动分配头尾两个指针。调用一次find方法,就会进行一次匹配操作。 第一次调用后,匹配到了abc三个字符,此时指针指向为:图2

此时调用start方法, 返回的就是上一次匹配操作之后,start指针指向的位置,为第一个字符的左边,调用end方法,返回的是end指针的位置,为第三个字符右边。所以,第一次调用start方法,返回结果为0,调用end方法返回结果为3。

第二次调用find方法后,指针向前移动:图3

此时调用start方法,返回3,调用end方法返回6。

以此类推,直到find方法返回false,匹配结束。

经过上面的数据结构分析可知,调用一次find方法得到的匹配内容,就称为“上一次匹配”,很多方法都必须依赖于find方法:比如说,start、end、group、groupCount, 还有reset方法虽然不直接依赖于find方法,但是也息息相关,调用reset方法后,头尾指针都将归零,重新开始。

正则分组

介绍完Matcher类的数据结构以后,继续介绍正则表达式中的另一个重要概念,正则分组。 正则分组主要是用于提取出,指定字符串中特定的子字符串。

正则分组,有两个重要的点:

1. ( ) 小括号的里面的内容分为一组,一个正则有n个小括号,就表示要分成n+1组,其中第0组,是全部匹配内容。

2. find, group,以及groupCount等相关方法。

正则分组分为捕获组、分组取名、非捕获组、分组复用,下面的例子将分别进行说明。

举例说明1 捕获组:

// 目标字符串,目标是要提前IOPS,avg的值String s = " IOPS=2932, bw=329,and other number avg=399, savg=23029";

// 正则。String regular = "^.*IOPS=(\\d+)\\b.*\\bavg=(\\d+)\\b.*$";

Matcher matcher = Pattern.compile(regular).matcher(s);

if(matcher.find() && matcher.groupCount() == 2) {

System.out.println(matcher.group(1));

System.out.println(matcher.group(2));

}

1. 对于正则表达式, ^ 匹配字符串开始位置; .* 匹配几个空格;IOPS=匹配IOPS=;\\d+匹配2932,作为第1组内容;\\b匹配2与,之间的位置;.* 匹配, bw=329,and other number ;\\b匹配空格与a之间的位置; avg=匹配avg=; \\d+匹配399;\\b匹配9与逗号之间的位置; .*匹配, savg=23029; $匹配结束位置。

2. 调用一次find方法,将匹配到全部字符串内容; 整个匹配内容被分成了三组,第0组是全部字符串内容,第1组得到2932, 第2组内容是399; 调用groupCount,不包括第0组,所以结果为2。

举例说明2 分组命名:

在进行分组设置的时候,还可以取组名。 取名格式为: (?exp), 然后用matcher.group(“groupName”) 取出组内匹配的内容

String s = " IOPS=2932, bw=329,and other number avg=399, savg=23029";

// 正则。String regular = "^.*IOPS=(?\\d+)\\b.*\\bavg=(?\\d+)\\b.*$";

Matcher matcher = Pattern.compile(regular).matcher(s);

if(matcher.find() && matcher.groupCount() == 2) {

System.out.println(matcher.group("group1"));

System.out.println(matcher.group("group2"));

}

举例说明3 非捕获组:

在进行分组的时候,可以给某些不那么重要的组,只分组不编号也不取名字。非捕获组的格式为: (?:exp)

// 目标字符串,获取avg的值 String s = " IOPS=2932, bw=329,and other number avg=399, savg=23029";

// 正则。 String regular = "^.*IOPS=(?:\\d+)\\b.*\\bavg=(\\d+)\\b.*$";

Matcher matcher = Pattern.compile(regular).matcher(s);

if(matcher.find() && matcher.groupCount() == 1) {

System.out.println(matcher.group(1));

}

可以看到,(?:\\d+) 匹配内容,但是不捕获文本,也不进行分组编号。整个字符串,除了第0组外,只有第1组。

举例说明4 分组复用:

正则分组后的复用。这个使用,主要牵扯到replaceFirst或者replaceAll方法。

// 目标字符串为手机号 String s = "18348236765";

// 正则。 String regular = "(\\d{3})\\d{4}(\\d{4})";

Matcher matcher = Pattern.compile(regular).matcher(s);

String result = matcher.replaceAll("$1****$2");

System.out.println(result);

该程序将把手机号进行模糊处理, 整个正则分为3组,第1组为前3位数字,第2组为后4位数字,所以替换时,使用$n,来表示引用第n组的内容。所以本例的输出结果为: 183****6765

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值