加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式(二)

发布时间:2020-12-13 19:51:20 所属栏目:百科 来源:网络整理
导读:转载:http://fuliang.iteye.com/blog/169946 正则表达式在处理文本方面用处非常大,最早像在Perl和awk语言中,提供了这种机制,Java在Java 2中也增加了正则表达式这个包java.util.regex。这个包为用户使用正则表达式,提供了易用而全面的支持。我的研究方向

转载:http://fuliang.iteye.com/blog/169946

正则表达式在处理文本方面用处非常大,最早像在Perl和awk语言中,提供了这种机制,Java在Java 2中也增加了正则表达式这个包java.util.regex。这个包为用户使用正则表达式,提供了易用而全面的支持。我的研究方向是web挖掘。从网页中提取内容,处理文本,当然需要正则表达式这个强大的工具了。
一、首先我们看一下怎么使用正则表达式的一个例子:
A Matcher examines the results of applying a pattern.
我们希望从这句话中找到所有开头为a的单词。
当然这只是一个简单的例子,你可以使用String提供的split方法,得到单词数组,然后
遍历各个单词看是否是否开头为a
我们现在看看怎么使用正则表达式来处理这个问题:

Java代码
  1. importjava.util.regex.*;
  2. publicclassFindA{
  3. staticvoidmain(Stringargs[])
  4. throwsException{
  5. Stringcandidate=
  6. "AMatcherexaminestheresultsofapplyingapattern.";
  7. Stringregex="baw*b";
  8. Patternp=Pattern.compile(regex);
  9. Matcherm=p.matcher(candidate);
  10. Stringval=null;
  11. System.out.println("INPUT:"+candidate);
  12. System.out.println("REGEX:"+regex+"rn");
  13. while(m.find()){
  14. val=m.group();
  15. System.out.println("MATCH:"+val);
  16. }
  17. if(val==null){
  18. System.out.println("NOMATCHES:");
  19. }

从这个例子我们可以看到正则表达式涉及到的两个类Matcher和Pattern,我们以后会专门讨论着连个类。现在主要看看使用正则表达式的流程:
首先使用 Pattern的一个静态的方法compile来创建Pattern对象,
Patternp=Pattern.compile(regex);

然后调用Pattern的方法matcher
Matcherm=p.matcher(candidate);
得到了Matcher对象,Matcher对象保存了许多匹配信息,然后可以通过find()方法
查找匹配的部分,如果有匹配的部分,返回真,使用m.group方法得到匹配的各组值,
否则find返回false.
当然这只是一般的过程,还有许多更细的方法,在以后会陆续的总结,下面我们看一下
Stringregex="baw*b";
这个就是一个正则表达式,b,w,*都是正则表达式的meta character原字符,
b表示单词的边界,w表示任意的可构成单词的字母数字,*表示前面的字母(当然可以
是更复杂的组之类的了东东)重复0次或0次以上,a当然还是a了。所以这个regex就
匹配单词开头为a的单词了。
二、下面总结一下基本的正则表达式的meta character以及它们含义:
. 匹配任意一个字符 $ 匹配一行的结尾 ^ 匹配一行的开头(在[]里面表示否定)
{} 定义了一个范围  [] 定义了一个字符类 () 定义了一个组
*前面出现0次以上 + 前面匹配一次以上 ?前面出现0次或一次  
 后面的字符不会看作metacharacter w 字母数字下划线 W 非字母数字下划线
d 单个数字 D单个非数字 | 或,二者之一 &&与操作符 b单词边界
下面看看几个简单的例子:
[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的静态工厂方法来扩展吧:
staticPatterncompile(Stringregex)
将给定的正则表达式编译到模式中,并创建Pattern对象,这个方法通常是操作正则表达式的第一步,从前面那个例子
我们也可以看到整个的流程。
在看看一个重载的compile方法:
staticPatterncompile(Stringregex,intflags)
将给定的正则表达式编译到具有给定标志的模式中。 这个方法参数flags提供了一些特殊的选项来用于特殊的处理,
我们下面看看可使用的选项:
UNIX_LINES:这个主要处理UNIX和其他的操作系统在行结束符不一样的问题,UNIX使用n代表一行的终止,而Windows
则使用了rn,n,r,u2028或者u0085作为一行的结束符。
CASE_INSENSITIVE:当我们在匹配的时候要忽略字符大小写时
COMMENTS:允许我们在正则表达式中使用注释,例如
Patternp=Pattern.compile("A#matchesuppercaseUS-ASCIIcharcode65",Pattern.COMMENTS);
MULTILINE:表明要输入多行,他们有自己的终止字符。
Patternp=Pattern.compile("^",Pattern.MULTILINE);
如果你的输入的字符串是:This is a sentence.n So is this..
这样我们匹配的字符时This中的T和So中的S,如果不使用MULTILINE,则只会匹配T
DOTALL:使用这个选项之后metacharacter .就可以包括一行的终止字符了,如果没有这个选项,
一行的终止字符,并不会考虑在字符串之内的。
使用这个选项会降低效率
Patternp=Pattern.compile(".",Pattern.DOTALL);
如果我们输入的是Testn,则匹配的字符是5个。
UNICODE_CASE:处理UNICODE字符集,使用这个选项会降低效率
CANON_EQ:一个字符的实际存储形式是经过编码后的数字,使用CANON_EQ选项就可以匹配一个字母在各种编码了。
例如a可以匹配+00E0和U+0061U+0300
我们可以组合以上选项,只要使用|,进行按位或操作即可
Patternp=
  • Pattern.compile("t#acompoundflagexample",Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CASE|
  • Pattern.COMMENT);

  • 我们还要注意点的时Java对转译字符的处理,例如我们要匹配一个数字:
    我们不能使用:
    Patternp=Pattern.compile("d");
    而是:
    Patternp=Pattern.compile("d");
    另外如果regex本身形式是错误的,compile方法会抛出java.util.regex.PatternSyntaxException异常。
    下面我们总结一下public Matcher matcher(CharSequence input)方法:
    当我们使用compile操作,创建了Pattern对象之后,我们就可以使用Pattern对象的matcher操作,生成
    matcher对象了,Matcher对象包含了许多对匹配结果集的操作,我们在总结Matcher对象的时候再说。另外
    顺便提一下参数CharSequence,CharBuffer,Segment,String,StringBuffer,StringBuilder 都实现了
    这个接口,所以参数可以是这些中的任一种类型了。
    下面我们看看:
    intflags()
    这个方法返回了我们前面可以设置的并且已经设置的flags选项,我们通过按位与来判断是否设置了某个选项:
    intflgs=myPattern.flags();
  • booleanisUsingCommentFlag=(Pattern.COMMENTS==(Pattern.COMMENTS&flgs));

  • 看看一个简化过程的方法:
    booleanmatches(Stringregex,CharSequenceinput)
    这个方法实际上是:
    m.matches()
    过程的一个简化,我们在后面总结Matcher中的matches方法之后就会理解这个了。
    想必我们经常使用把字符串提取出token变成字符串数组的String中的split方法吧,下面我们看看
    类似的一个方法:
    public String[] split(CharSequence input)
    这个方法提供了强大的功能,因为它可以使用正则表达式来作为token的分割:
    Patternp=newPattern.compile(",|and");
  • Stringfruits[]=p.split("apple,bananaandorange");

  • split的一个重载的版本:
    publicString[]split(CharSequenceinput,85); font-weight:bold">intlimit)
    它指定了划分的组数,有以下三种情况:
    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,Favorite";

  • limit<0
    会尽可能的划分所有的组,即使分割符后面是个空字符,也要单独生成一个token:""
    Patternp=Pattern.compile(",");
  • Stringtemp[]=p.split("Hello,",-1);
  • //temp[]={"Hello","Dolly",""}

  • 下次再总结Matcher类,和正则表达式的一些高级部分

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读