Java正则表达式分组实验

来源:互联网 发布:网络电影演员火不了 编辑:程序博客网 时间:2024/06/08 02:26

正则表达式的使用无非就四个步骤:

  1. 定义匹配规则,就是一串负责正则表达式语法的字符串,我们叫它patternStr
  2. 使用Pattern类去编译patternStr,得到Pattern实例patternIns(注意Pattern并没有提供公共构造方法)
  3. 使用patternIns的matcher方法解析需要匹配的字符串targetStr,得到Matcher类的实例matcherIns
  4. 有了matcherIns,你就可以:

    1) 查找是否有匹配规则的字符 matcherIns.find()
    2) 获取匹配后的分组matcherIns.group()
    ……..

正则表达式在实际的项目中用得很少,过一段时间后就很容易忘记,偶尔翻看了下以前正则表达式的资料,发现了个有趣的例子。

这是一段测试捕获组的代码,引用自runoob.com:

http://www.runoob.com/java/java-regular-expressions.html

捕获组
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
例如,正则表达式 (dog) 创建了单一分组,组里包含”d”,”o”,和”g”。
捕获组是通过从左至右计算其开括号来编号。例如,在表达式((A)(B(C))),有四个这样的组:
((A)(B(C)))
(A)
(B(C))
(C)
可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。
还有一个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中。

先上代码:

import java.util.regex.Matcher;import java.util.regex.Pattern;public class PatternDemo {    public static void main(String[] args) {        // TODO Auto-generated method stub        String line = "This order was placed for QT3000a! OK?";        String patternStr = "(.*)(\\d+)(.*)";        Pattern p = Pattern.compile(patternStr);        Matcher m = p.matcher(line);        System.out.println("Match num = " + m.groupCount());        if(m.find()){            System.out.println(m.group(0));            System.out.println(m.group(1));            System.out.println(m.group(2));        }else{            System.out.println("NO MATCH");        }    }}

运行后我们得到如下结果:

Match num = 3This order was placed for QT3000a! OK?This order was placed for QT3000

这个时候我懵逼了,第二个匹配规则(\d+)不是指匹配*到多个数字吗,为什么没有匹配整个数字串3000,仅仅匹配了0

而(.*)却也只是匹配了This order was placed for QT300, 不是 This order was placed for QT3000a! OK?

这成功引起了我的注意

这里写图片描述

华丽的分割线


我们看到,Match num = 3,也就是说,我们还有一个捕获组还没打印出来,来,我们加上

System.out.println(m.group(3));

运行结果:

Match num = 3This order was placed for QT3000a! OK?This order was placed for QT3000a! OK?

嗯…剩下的匹配看起来木有问题…. 那么问题出在哪里呢? 让我们多做几个实验,首先我们修改匹配规则串patternStr,多加一个数字匹配(\d+):

    String patternStr = "(.*)(\\d+)(\\d+)(.*)";

得到的结果是这样的:

Match num = 4This order was placed for QT3000a! OK?This order was placed for QT3000a! OK?

噢?! group(1)少匹配了一个0,很明显这个0被新加的(\d+)夺走了,我再改一下,把(\d+)改成(\d*)

String patternStr = "(.*)(\\d+)(\\d*)(.*)";

结果

Match num = 4This order was placed for QT3000a! OK?This order was placed for QT3000a! OK?

group(3)的0被夺走了… 最后一个实验

String patternStr = "(.*)(\\d*)(\\d*)(.*)";

结果,为了让大家知道各个分组的位置,我用<–group(num)标记了一下

Match num = 4This order was placed for QT3000a! OK?  <--group0)This order was placed for QT3000a! OK?<--group1)<--group2)<--group3)<--group4

终于有头绪了,捕获组的匹配都是贪婪模式的,越是排在前面的捕获组,匹配的优先级就越高,在满足其余捕获组的最低要求(如 + 最低要求匹配一个)的前提下,优先级越高的捕获组,会尽可能地匹配所有符合的字符。

至此,一切真相大白,温故而知新,这句话一点都没错!!

脑袋空空,口袋空空!

原创粉丝点击