java 正则表达式(() [] {}有不同的意思)、Pattern和Matcher详解

结论:
1、Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持.
2、单独用Pattern只能使用Pattern.matcher(String regex,CharSequence input)一种最基础最简单的匹配。

1、正则表达式基础


其中反义代码为w,s,d,b的大写

2.正则表达式的() [] {}有不同的意思。
  1).() 是为了提取匹配的字符串。表达式中有几个()就有几个相应的匹配字符串。
    (\s*)表示连续空格的字符串。
  2).[]是定义匹配的字符范围。比如 [a-zA-Z0-9] 表示相应位置的字符要匹配英文字符和数字。[\s*]表示空格或者*号。
  3).{}一般用来表示匹配的长度,比如 \s{3} 表示匹配三个空格,\s[1,3]表示匹配一到三个空格。

  (0-9) 匹配 '0-9′ 本身。 [0-9]* 匹配数字(注意后面有 *,可以为空)[0-9]+ 匹配数字(注意后面有 +,不可以为空){1-9} 写法错误。
  [0-9]{0,9} 表示长度为 0 到 9 的数字字符串。

正则表达式30分钟入门教程http://www.jb51.net/tools/zhengze.html

2、Pattern类与Matcher类

java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现(建议在阅读本文时,打开java API文档,当介绍到哪个方法时,查看java API中的方法说明,效果会更佳).
Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,

1.1、Pattern.complie(String regex):简单工厂方法创建一个正则表达式;
pattern() 返回正则表达式的字符串形式,其实就是返回Pattern.complile(String regex)的regex参数

    @Test
    public void testCompile() {
        Pattern p = Pattern.compile("\\w+");
        System.out.println(p.pattern());  //返回 \w+
    }
1.2、Pattern.split(CharSequence input)
Pattern有一个split(CharSequence input)方法,用于分隔字符串,并返回一个String[],我猜String.split(String regex)就是通过Pattern.split(CharSequence input)来实现的.
    @Test
    public void testSpilt(){
        Pattern p= Pattern.compile("\\d+");
        String[] str=p.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");

        for(String a : str){
            System.out.println(a);
        }
    }
结果是:我的QQ是:
              我的电话是:
              我的邮箱是:aaa@aaa.com
1.3.Pattern.matcher(String regex,CharSequence input)
是一个静态方法,用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串.
    @Test
    public void testMatches() {
        //返回true
        System.out.println(Pattern.matches("\\d+","2223"));

        //返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
        System.out.println(Pattern.matches("\\d+","2223aa"));

        //返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到
        System.out.println(Pattern.matches("\\d+","22bb23"));
    }

1.4、Pattern.matcher(CharSequence input):返回一个Matcher对象
Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例.
Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持.

    @Test
    public void test() {
        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher("22bb23");

        //返回值为\d+ ,也就是返回该Matcher对象是由哪个Pattern对象的创建的
        System.out.println(m.pattern());
    }
1.5、Matcher.matches()/ Matcher.lookingAt()/ Matcher.find()
Matcher类提供三个匹配操作方法,三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false
 
1.5.1、matches()对整个字符串进行匹配,只有整个字符串都匹配了才返回true
    @Test
    public void testMatches2() {
        Pattern p = Pattern.compile("\\d+");

        Matcher m = p.matcher("22bb23");
        //返回false,因为bb不能被\d+匹配,导致整个字符串匹配未成功.
        System.out.println(m.matches());

        Matcher m2 = p.matcher("2223");
        //返回true,因为\d+匹配到了整个字符串
        System.out.println(m2.matches());
    }
我们现在回头看一下Pattern.matcher(String regex,CharSequence input),
等价 Pattern.compile(regex).matcher(input).matches()
1.5.2、lookingAt()对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true
    @Test
    public void testLookingAt() {
        Pattern p = Pattern.compile("\\d+");

        Matcher m = p.matcher("22bb23");
        //返回true,因为\d+匹配到了前面的22
        System.out.println(m.lookingAt());

        Matcher m2 = p.matcher("aa2223");
        //返回false,因为\d+不能匹配前面的aa
        System.out.println(m2.lookingAt());
    }
1.5.3、find()对字符串进行匹配,匹配到的字符串可以在任何位置.
    @Test
    public void testFind() {
        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher("22bb23");
        System.out.println(m.find()); //返回true

        Matcher m2 = p.matcher("aa2223");
        System.out.println(m2.find()); //返回true

        Matcher m3 = p.matcher("aa2223bb");
        System.out.println(m3.find()); //返回true

        Matcher m4 = p.matcher("aabb");
        System.out.println(m4.find()); //返回false
    }
1.6、Mathcer.start()/ Matcher.end()/ Matcher.group()
当使用matches(),lookingAt(),find()执行匹配操作后,就可以利用以上三个方法得到更详细的信息.
start()返回匹配到的子字符串在字符串中的索引位置.
end()返回匹配到的子字符串的最后一个字符在字符串中的索引位置.
group()返回匹配到的子字符串
    @Test
    public void test4() {
        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher("aaa2223bb");
        System.out.println(m.find());  //匹配2223,返回true
        System.out.println(m.start());  //返回3
        System.out.println(m.end());   //返回7,返回的是2223后的索引号
        System.out.println(m.group());  //返回2223

        Matcher m2 = p.matcher("2223bb");
        System.out.println(m2.lookingAt());  //匹配2223,返回true
        //返回0,由于lookingAt()只能匹配前面的字符串,所以当使用lookingAt()匹配时,start()方法总是返回0
        System.out.println(m2.start());
        System.out.println(m2.end());   //返回4
        System.out.println(m2.group());  //返回2223

        //如果Matcher m3=p.matcher("2223"); 那么下面的方法出错,因为不匹配返回false
        Matcher m3 = p.matcher("2223bb");
        System.out.println(m3.matches());  //匹配整个字符串,,返回true
        System.out.println(m3.start());  //返回0
        System.out.println(m3.end());   //返回4,
        System.out.println(m3.group());  //返回2223
    }
1.7、start(),end(),group()均有一个重载方法它们是start(int i),end(int i),group(int i)专用于分组操作,
Mathcer类还有一个groupCount()用于返回有多少组.
    @Test
    public void test2() {
        Pattern p = Pattern.compile("([a-z]+)(\\d+)");
        Matcher m = p.matcher("aaa2223bb");
        System.out.println(m.find());  //匹配aaa2223,返回true
        System.out.println(m.groupCount());   //返回2,因为有2组
        
        System.out.println(m.start(1));   //返回0 返回第一组匹配到的子字符串在字符串中的索引号
        System.out.println(m.start(2));   //返回3
        
        System.out.println(m.end(1)); //返回3 返回第一组匹配到的子字符串的最后一个字符在字符串中的索引位置.
        System.out.println(m.end(2));   //返回7
        
        System.out.println(m.group(1));   //返回aaa,返回第一组匹配到的子字符串
        System.out.println(m.group(2));    //返回2223,返回第二组匹配到的子字符串
    }

现在我们使用一下稍微高级点的正则匹配操作,例如有一段文本,里面有很多数字,而且这些数字是分开的,我们现在要将文本中所有数字都取出来,利用java的正则操作是那么的简单.
    @Test
    public void test3() {
        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com");
        
        while (m.find()) {
            System.out.println(m.group());
            System.out.print("start:" + m.start());
            System.out.println(" end:" + m.end());
        }
    }
456456
start:6 end:12
0532214
start:19 end:26
123
start:36 end:39

现在大家应该知道,每次执行匹配操作后start(),end(),group()三个方法的值都会改变,改变成匹配到的子字符串的信息,以及它们的重载方法,也会改变成相应的信息.
注意:只有当匹配操作成功,才可以使用start(),end(),group()三个方法,否则会抛出java.lang.IllegalStateException,也就是当matches(),lookingAt(),find()其中任意一个方法返回true时,才可以使用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值