Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 429|回复: 0

[正则表达式学习]学习正则表达式:Pattern类

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-30 00:00:20 | 显示全部楼层 |阅读模式
    正则表达式在处理文本方面用处非常大,最早像在Perl和awk语言中,提供了这种机制,java在Java 2中也增加了正则表达式这个包java.util.regex。这个包为用户使用正则表达式,提供了易用而全面的支持。

         我的研究方向是web挖掘。从网页中提取内容,处理文本,当然需要正则表达式这个强大的工具了。

    一、首先我们看一下怎么使用正则表达式的一个例子:
    A Matcher examines the results of applying a pattern.
    我们希望从这句话中找到所有开头为a的单词。

       当然这只是一个简单的例子,你可以使用String提供的split方法,得到单词数组,然后 遍历各个单词看是否是否开头为a
    我们现在看看怎么使用正则表达式来处理这个问题:   
      
       
       
         
       

         
       
      
    1. import java.util.regex.*;   
    2.   
    3. public class FindA{   
    4.   public static void main(String args[])   
    5.   throws Exception{   
    6.   
    7.     String candidate ="A Matcher examines the results of applying a pattern.";   
    8.     String regex = "\ba\w*\b";   
    9.     Pattern p = Pattern.compile(regex);   
    10.     Matcher m = p.matcher(candidate);   
    11.     String val = null;   
    12.     System.out.println("INPUT: " + candidate);   
    13.     System.out.println("REGEX: " + regex +"
    14. ");   
    15.     while (m.find()){   
    16.       val = m.group();   
    17.       System.out.println("MATCH: " + val);   
    18.     }   
    19.     if (val == null) {   
    20.       System.out.println("NO MATCHES: ");   
    21.     }   
    22.   }   
    23. }  
    复制代码

          从这个例子我们可以看到正则表达式涉及到的两个类Matcher和Pattern,我们以后会专门讨论着连个类。现在主要看看使用正则表达式的流程:
    首先使用Pattern的一个静态的方法compile来创建Pattern对象,
    Pattern p = Pattern.compile(regex);
    然后调用Pattern的方法matcher
    Matcher m = p.matcher(candidate);
                      [/code] 得到了Matcher对象,Matcher对象保存了许多匹配信息,然后可以通过find()方法查找匹配的部分,如果有匹配的部分,返回真,使用m.group方法得到匹配的各组值,
    否则find返回false.
    当然这只是一般的过程,还有许多更细的方法,在以后会陆续的总结,下面我们看一下
    String regex = "\ba\w*\b";

    这个就是一个正则表达式,b,w,*都是正则表达式的meta character原字符,

       表示单词的边界,w表示任意的可构成单词的字母数字,*表示前面的字母(当然可以是更复杂的组之类的了东东)重复0次或0次以上,

    a当然还是a了。所以这个regex就匹配单词开头为a的单词了。

    二、下面总结一下基本的正则表达式的meta character以及它们含义:
    .匹配任意一个字符 $ 匹配一行的结尾 ^ 匹配一行的开头(在[]里面表示否定)

    {} 定义了一个范围  [] 定义了一个字符类 () 定义了一个组

    *前面出现0次以上   + 前面匹配一次以上 ?前面出现0次或一次  

     后面的字符不会看作metacharacter  w 字母数字下划线 W 非字母数字下划线

    d 单个数字 D单个非数字 | 或,二者之一 &&与操作符 单词边界

    下面看看几个简单的例子:

    [abc] a、b 或 c(简单类)

    [^abc]
    任何字符,除了a、b 或 c(否定)

    [a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)

    [a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)

    [a-z&&[def]] d、e 或 f(交集)

    [a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)

    [a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)

    三、java.util.regex提供的操作接口:

    java.util.regex包提供了操作正则表达式的模型,整个模型优雅而简洁,只有三个类:Pattern、Matcher和

    PatternSyntaxException。下面将要总结他们提供的方法,以及如何灵活应用来处理文本。

    我们还是从Pattern的静态工厂方法来扩展吧: [/code] static Pattern compile(String regex)                 [/code] ??? 将给定的正则表达式编译到模式中,并创建Pattern对象,这个方法通常是操作正则表达式的第一步,从前面那个例子
    我们也可以看到整个的流程。
    在看看一个重载的compile方法:

    static Pattern compile(String regex, int flags)               [/code] 将给定的正则表达式编译到具有给定标志的模式中。 这个方法参数flags提供了一些特殊的选项来用于特殊的处理,
    我们下面看看可使用的选项:   UNIX_LINES:这个主要处理UNIX和其他的操作系统在行结束符不一样的问题,UNIX使用
    代表一行的终止,而Windows
    则使用了
    ,
    ,
    ,u2028或者u0085作为一行的结束符。

    CASE_INSENSITIVE:当我们在匹配的时候要忽略字符大小写时

    COMMENTS:允许我们在正则表达式中使用注释,例如  Pattern p =Pattern.compile("A    #matches uppercase US-ASCII char code 65",Pattern.COMMENTS);              [/code] MULTILINE:表明要输入多行,他们有自己的终止字符。
    Pattern p = Pattern.compile("^.", Pattern.MULTILINE);            [/code] 如果你的输入的字符串是:This is a sentence.
    So is this..
    这样我们匹配的字符是This中的T和So中的S,如果不使用MULTILINE,则只会匹配T
    程序:
    1. import java.util.regex.*;   
    2.   
    3. public class Multiline{   
    4.   public static void main(String args[])   
    5.   throws Exception{   
    6.   
    7.     String candidate ="This is a sentence.
    8. So is this..";   
    9.     String regex = "^.";   
    10.     Pattern p = Pattern.compile("^.", Pattern.MULTILINE);   
    11.     //Pattern p = Pattern.compile(regex,Pattern.MULTILINE);   
    12.     Matcher m = p.matcher(candidate);   
    13.     String val = null;   
    14.     System.out.println("INPUT: " + candidate);   
    15.     System.out.println("REGEX: " + regex +"
    16. ");   
    17.     while (m.find()){   
    18.       val = m.group();   
    19.       System.out.println("MATCH: " + val);   
    20.     }   
    21.     if (val == null) {   
    22.       System.out.println("NO MATCHES: ");   
    23.     }   
    24.   }   
    25. }  
    复制代码
    DOTALL:使用这个选项之后metacharacter .就可以包括一行的终止字符了,如果没有这个选项, 一行的终止字符,并不会考虑在字符串之内的。 使用这个选项会降低效率
    Pattern p = Pattern.compile(".", Pattern.DOTALL);              [/code] 如果我们输入的是Test
    ,则匹配的字符是5个。   我们可以组合以上选项,只要使用|,进行按位或操作即可  Pattern p =
      Pattern.compile("t # a compound flag example",Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE|Pattern.COMMENT);
                      [/code] 我们还要注意点的是Java对转译字符的处理,例如我们要匹配一个数字:
    我们不能使用:
    Pattern p = Pattern.compile("d");            [/code] 而是:
    Pattern p = Pattern.compile("\d");               [/code] 另外如果regex本身形式是错误的,compile方法会抛出java.util.regex.PatternSyntaxException异常。

    下面我们总结一下public Matcher matcher(CharSequence input)方法:
         当我们使用compile操作,创建了Pattern对象之后,我们就可以使用Pattern对象的matcher操作,生成 matcher对象了,Matcher对象包含了许多对匹配结果集的操作,我们在总结Matcher对象的时候再说。另外 顺便提一下参数CharSequence,CharBuffer, Segment, String, StringBuffer, StringBuilder 都实现 这个接口,所以参数可以是这些中的任一种类型了。
    下面我们看看:
    public int flags()
    [/code] 这个方法返回了我们前面可以设置的并且已经设置的flags选项,我们通过按位与来判断是否设置了某个选项:
    int flgs = myPattern.flags();
    boolean isUsingCommentFlag =( Pattern.COMMENTS == (Pattern.COMMENTS & flgs)) ;
    [/code]
    看看一个简化过程的方法:
    public static boolean matches (String regex,CharSequence input)
    [/code]
    这个方法实际上是:
      Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(candidate);
    m.matches()
    [/code] 过程的一个简化,我们在后面总结Matcher中的matches方法之后就会理解这个了。 想必我们经常使用把字符串提取出token变成字符串数组的String中的split方法吧,下面我们看看 类似的一个方法:

    public String[] split(CharSequence input)

    这个方法提供了强大的功能,因为它可以使用正则表达式来作为token的分割:
      Pattern p = new Pattern.compile(",|and");
    String fruits[] = p.split("apple,banana and orange");
    [/code] split的一个重载的版本:
    public String[] split(CharSequence input, int limit)
    [/code] 它指定了划分的组数,有以下三种情况:
    limit==0
    这时候和没有limit参数的那个split效果一样
    limit>0
    如果你仅仅对前limit个感兴趣,你可以使用limit:
    String[] tmp = pattern.split("Hello, Dolly, You, Are, My, Favorite",3);
    //tmp[0] is  "Hello",
    // tmp[1] is "Dolly";
    //tmp[2] is  "You, Are, My, Favorite";
    [/code]
    limit<0
    会尽可能的划分所有的组,即使分割符后面是个空字符,也要单独生成一个token:""
    Pattern p = Pattern.compile(",");
    String temp[] = p.split("Hello,Dolly,", -1);
    //temp[]={"Hello","Dolly",""}
    [/code]

      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/10/28/235849421.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-19 01:08 , Processed in 0.381733 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表