zoukankan      html  css  js  c++  java
  • java正则表达式

    在做 Crawler的时候,本来是准备用正则的,但是看jsoup很好用,就没有学,刚刚在做古诗提取的时候,又要用到正则表达式,还是学了算了。

    说明:

    文章重点参考的http://www.cnblogs.com/ggjucheng/p/3423731.html,加上自己有一点理解。

    正则表达式的语法可以参考:

    http://www.runoob.com/regexp/regexp-syntax.html

    java正则表达式主要是关于java.util.regex中的两个类:

    1.Pattern:正则表达式经过编译后的表现模式。

    2.Matcher:一个Matcher对象是一个状态机,它依据Pattern对象做为匹配模式对字符串展开匹配检查。

    两者的关系是,Matcher在Pattern给定的模式控制下进行字符串匹配工作。

     

    在正式开始正则表达式学习前,先要理解捕获组的概念。

    一.捕获组的概念

      捕获组就是将正则表达式中子表达式匹配的内容,保存到内存中,并以数字的编号或者显示命令的组里,方便后面的引用。主要分为两种,其语法如下:

    (1)普通捕获组:(expression)

    大多数语言都支持,这也是我们学习的重点。

    (2)命名捕获组:(?<name>expression)

    暂不分析。

    要注意的是,除这两种语法外,其它的语法都不是捕获组。

    捕获组的编号:从左到右计算其开括号 "(" 来进行编号,且从1开始,因为编号0是正则表达式整体。

    例子:

    匹配格式为yyyy-mm-dd的日期。

    private static void study1(){
            String line = "2016-02-15";
            String pattern = "(\d{4})-(\d{2}-(\d\d))";
            //([0-9])=(//d)
    
            //pattern对象是一个正则表达式的编译表示
            Pattern r = Pattern.compile(pattern);
    
            //Matcher对象是对输入字符串进行解释和匹配操作的引擎。
            Matcher m = r.matcher(line);
            System.out.println("group:"+ m.groupCount());
            if (m.find()){
                System.out.println("Found value: "+ m.group(0));//all
                System.out.println("Found Value: "+ m.group(1));//(\d{4})
                System.out.println("Found value: "+ m.group(2));//(\d{2})
                System.out.println("Found value: "+ m.group(3));//(\d\d)
    
            }else {
                System.out.println("No match");
            }
        }
    

     输出结果为

    group:3
    Found value: 2016-02-15
    Found Value: 2016
    Found value: 02-15
    Found value: 15

    二.Pattern类的使用

      用于创建一个正则表达式,也可以说是一个匹配模式,其构造方法是私有的,但可以通过Pattern.compile(regex)简单工厂方法来创建一个正则表达式。

    例子:查看regex参数

    Pattern pattern = Pattern.compile("\w+");
    System.out.println(pattern.toString());
    System.out.println(pattern.pattern());
    

     结果

    w+
    w+

    返回的都是正则表达式的字符串形式。

    (1)pattern.split(Charsequence input)

      用于分隔字符串,并返回一个String [ ],是否String.split(String regex) 就是通过这个实现的呢?

    Pattern pattern = Pattern.compile("\d");
            String [] strArray =pattern.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");
            for (String aftersplit: strArray){
                System.out.println(aftersplit);
            }
    

     结果为:

    str[0]="我的QQ是:" str[1]="我的电话是:" str[2]="我的邮箱是:aaa@aaa.com"

    (2) Pattern.matcher(String regex,CharSequence input)

      静态方法,用于快速匹配字符串,适用于只匹配一次,且匹配全部字符串。

    例子:

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

     (3)Pattern.matcher(CharSequence input)

      Matcher出现了,这个方法返回一个Matcher,其没有公共构造方法(私有的),只能通过 Pattern.matcher得到。

    上面我们看到,Pattern只能做一此简单的匹配,要得到更强大的正则匹配,则要用到Matcher,Matcher提供了对正则表达式分组与多次匹配的支持。

    例子:

    Pattern p = Pattern.compile("\d+");
            Matcher m = p.matcher("22bb33");
            System.out.println(m.pattern());
            System.out.println(m.toString());
    

     结果为

    d+
    java.util.regex.Matcher[pattern=d+ region=0,6 lastmatch=]

    可以看到,matcher.toString()会返匹配的情况。

     (4)Matcher.matches()/Matcher.lookingAt()/Matcher.find()

      Matcher类提供三个匹配操作方法,它们都返回boolean类型,匹配成功时返回 true。

    matches()

    对整个字符串进行匹配,只有整个字符串都匹配了才返回true。

     Pattern p = Pattern.compile("\d+");
            Matcher m = p.matcher("22bb33");
            System.out.println(m.matches());
            Matcher m2 = p.matcher("2233");
            System.out.println(m2.matches());
    

     返回结果

    false, true

    我们可以发现,下面的两种代码等价:

    Pattern.matches(String regex,CharSequence input)

    Pattern.compile(regex).matcher(input).matches()

    lookingAt()

    对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true。

    Pattern p = Pattern.compile("\d+");
            Matcher m = p.matcher("22bb33");
            System.out.println(m.lookingAt()); //ture
            Matcher m2 = p.matcher("aa2233");
            System.out.println(m2.lookingAt());//flase
    

     find()

    匹配到的字符串可以在任何位置。

    Pattern p=Pattern.compile("\d+"); 
    Matcher m=p.matcher("22bb23"); 
    m.find();//返回true 
    Matcher m2=p.matcher("aa2223"); 
    m2.find();//返回true 
    Matcher m3=p.matcher("aa2223bb"); 
    m3.find();//返回true 
    Matcher m4=p.matcher("aabb"); 
    m4.find();//返回false 
    

     (5)Matcher.start()/Matcher.end()/Matcher.group()

      在使用matches()/lookingAt(),find()执行匹配操作后,就可以利用上面的三个方法得到更详细的信息。

    start():返回匹配到的子字符串在字符串中的索引的位置。

    end():返回匹配到的子字符串的最后一个字符在字符串中的位置。

    group():返回匹配到的子字符串。

     Pattern p = Pattern.compile("\d+");
            Matcher m = p.matcher("aaaa2222bb");
            m.find();//
            System.out.println(m.start());//4
            System.out.println(m.end());  //8
            System.out.println(m.group());//2222
    
            Matcher m2 = p.matcher("2222bb");
            m2.lookingAt();
            System.out.println(m2.start());//0
            System.out.println(m2.end());  //4
            System.out.println(m2.group());//222
    
            Matcher m3 = p.matcher("222");
            m3.matches();
            System.out.println(m3.start());//0
            System.out.println(m3.end());  //3
            System.out.println(m3.group());//222
    

     下面再说说正则表达式分组的使用,start(),end(),group(),它们都有加入参数int index的重载方法,用于分组操作。

    例子:

         Pattern p = Pattern.compile("([a-z]+)(\d+)");//2 groups
            Matcher m = p.matcher("aaa2223bb444");
            System.out.println(m.groupCount());//2
            while (m.find()){
                System.out.println("====one match");
                //all
                System.out.print(m.start(0)+",");//0,
                System.out.print(m.end(0)+",");   //7
                System.out.println(m.group(0));  //aaa2223
                //group 1
                System.out.print(m.start(1)+",");//0
                System.out.print(m.end(1)+",");   //3
                System.out.println(m.group(1));  //aaa
                //goup 2
                System.out.print(m.start(2)+",");//3
                System.out.print(m.end(2)+",");  //7
                System.out.println(m.group(2));//2223
            }
    

     输出

    2
    ====one match
    0,7,aaa2223
    0,3,aaa
    3,7,2223
    ====one match
    7,12,bb444
    7,9,bb
    9,12,444

    源码显示,无参数时是直接调用的参数为0的值,要注意的是,只有匹配成功时才可以使用start,end,group。

    最后一个例子,查找字符串中的数字:

            Pattern p = Pattern.compile("\d+");
            Matcher m = p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com");
            while (m.find()){
                System.out.println(m.group());
            }    
    

     

  • 相关阅读:
    关于 Android 进程保活,你所需要知道的一切【转】
    android 按返回键最小化(后台运行)
    android notification完全解析【转】
    使用WakeLock使Android应用程序保持后台唤醒
    [Linux]Vim基本操作
    [STL]map的使用
    [python]使用python进行LINUX系统操作
    python challenge 2:迭代与列表
    python challenge 1、3:字符串处理
    python challenge 0:操作符与内建函数
  • 原文地址:https://www.cnblogs.com/chuiyuan/p/5187359.html
Copyright © 2011-2022 走看看