正则表达式详细讲解Word格式文档下载.docx

上传人:b****3 文档编号:16675393 上传时间:2022-11-25 格式:DOCX 页数:47 大小:226.79KB
下载 相关 举报
正则表达式详细讲解Word格式文档下载.docx_第1页
第1页 / 共47页
正则表达式详细讲解Word格式文档下载.docx_第2页
第2页 / 共47页
正则表达式详细讲解Word格式文档下载.docx_第3页
第3页 / 共47页
正则表达式详细讲解Word格式文档下载.docx_第4页
第4页 / 共47页
正则表达式详细讲解Word格式文档下载.docx_第5页
第5页 / 共47页
点击查看更多>>
下载资源
资源描述

正则表达式详细讲解Word格式文档下载.docx

《正则表达式详细讲解Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《正则表达式详细讲解Word格式文档下载.docx(47页珍藏版)》请在冰豆网上搜索。

正则表达式详细讲解Word格式文档下载.docx

  第一步,创建一个pattern对象来匹配上面的子字符串。

一旦程序运行后,如果需要的话,可以让这个对象一般化。

匹配上面格式的正则表达可以这样构成:

(/d{3})/s/d{3}-/d{4},其中/d单字符类型用来匹配从0到9的任何数字,另外{3}重复符号,是个简便的记号,用来表示有3个连续的数字位,也等效于(/d/d/d)。

/s也另外一个比较有用的单字符类型,用来匹配空格,比如Space键,tab键和换行符。

  是不是很简单?

但是,如果把这个正则表达式的模式用在java程序中,还要做两件事。

对java的解释器来说,在反斜线字符(/)前的字符有特殊的含义。

在java中,与regex有关的包,并不都能理解和识别反斜线字符(/),尽管可以试试看。

但为避免这一点,即为了让反斜线字符(/)在模式对象中被完全地传递,应该用双反斜线字符(/)。

此外圆括号在正则表达中两层含义,如果想让它解释为字面上意思(即圆括号),也需要在它前面用双反斜线字符(/)。

也就是像下面的一样:

  //(//d{3}//)//s//d{3}-//d{4}

  现在介绍怎样在java代码中实现刚才所讲的正则表达式。

要记住的事,在用正则表达式的包时,在你所定义的类前需要包含该包,也就是这样的一行:

  importjava.util.regex.*;

  下面的一段代码实现的功能是,从一个文本文件逐行读入,并逐行搜索电话号码数字,一旦找到所匹配的,然后输出在控制台。

  BufferedReaderin;

  Patternpattern=Ppile("

//(//d{3}//)//s//d{3}-//d{4}"

);

  in=newBufferedReader(newFileReader("

phone"

));

  Strings;

  while((s=in.readLine())!

=null)

  {

  Matchermatcher=pattern.matcher(s);

  if(matcher.find())

  System.out.println(matcher.group());

  }

  in.close();

  对那些熟悉用Python或Javascript来实现正则表达式的人来说,这段代码很平常。

在Python和Javascript这些语言中,或者其他的语言,这些正则表达式一旦明确地编译过后,你想用到哪里都可以。

与Perl的单步匹配相比,看起来多多做了些工作,但这并不很费事。

  find()方法,就像你所想象的,用来搜索与正则表达式相匹配的任何目标字符串,group()方法,用来返回包含了所匹配文本的字符串。

应注意的是,上面的代码,仅用在每行只能含有一个匹配的电话号码数字字符串时。

可以肯定的说,java的正则表达式包能用在一行含有多个匹配目标时的搜索。

本文的原意在于举一些简单的例子来激起读者进一步去学习java自带的正则表达式包,所以对此就没有进行深入的探讨。

  这相当漂亮吧!

但是很遗憾的是,这仅是个电话号码匹配器。

很明显,还有两点可以改进。

如果在电话号码的开头,即区位号和本地号码之间可能会有空格。

我们也可匹配这些情况,则通过在正则表达式中加入/s?

来实现,其中?

元字符表示在模式可能有0或1个空格符。

  第二点是,在本地号码位的前三位和后四位数字间有可能是空格符,而不是连字号,更有胜者,或根本就没有分隔符,就是7位数字连在一起。

对这几种情况,我们可以用(-|)?

来解决。

这个结构的正则表达式就是转换器,它能匹配上面所说的几种情况。

在()能含有管道符|时,它能匹配是否含有空格符或连字符,而尾部的?

元字符表示是否根本没有分隔符的情况。

  最后,区位号也可能没有包含在圆括号内,对此可以简单地在圆括号后附上?

元字符,但这不是一个很好的解决方法。

因为它也包含了不配对的圆括号,比如"

(555"

或"

555)"

相反,我们可以通过另一种转换器来强迫让电话号码是否带有有圆括号:

(/(/d{3}/)|/d{3})。

如果我们把上面代码中的正则表达式用这些改进后的来替换的话,上面的代码就成了一个非常有用的电话号码数字匹配器:

  Patternpattern=

  Ppile("

(//(//d{3}//)|//d{3})//s?

//d{3}(-|)?

//d{4}"

  可以确定的是,你可以自己试着进一步改进上面的代码。

  现在看看第二个例子,它是从Friedl的中改编过来的。

其功能是用来检查文本文件中是否有重复的单词,这在印刷排版中会经常遇到,同样也是个语法检查器的问题。

  匹配单词,像其他的一样,也可以通过好几种的正则表达式来完成。

可能最直接的是/b/w+/b,其优点在于只需用少量的regex元字符。

其中/w元字符用来匹配从字母a到u的任何字符。

+元字符表示匹配匹配一次或多次字符,/b元字符是用来说明匹配单词的边界,它可以是空格或任何一种不同的标点符号(包括逗号,句号等)。

  现在,我们怎样来检查一个给定的单词是否被重复了三次?

为完成这个任务,需充分利用正则表达式中的所熟知的向后扫描。

如前面提到的,圆括号在正则表达式中有几种不同的用法,一个就是能提供组合类型,组合类型用来保存所匹配的结果或部分匹配的结果(以便后面能用到),即使遇到有相同的模式。

在同样的正则表达中,可能(也通常期望)不止有一个组合类型。

在第n个组合类型中匹配结果可以通过向后扫描来获取到。

向后扫描使得搜索重复的单词非常简单:

/b(/w+)/s+/1/b。

  圆括号形成了一个组合类型,在这个正则表示中它是第一组合类型(也是仅有的一个)。

向后扫描/1,指的是任何被/w+所匹配的单词。

我们的正则表达式因此能匹配这样的单词,它有一个或多个空格符,后面还跟有一个与此相同的单词。

注意的是,尾部的定位类型(/b)必不可少,它可以防止发生错误。

如果我们想匹配"

Parisinthethespring"

,而不是匹配"

Java'

sregexpackageisthethemeofthisarticle"

根据java现在的格式,则上面的正则表达式就是:

Patternpattern=Ppile("

//b(//w+)//s+//1//b"

  最后进一步的修改是让我们的匹配器对大小写敏感。

比如,下面的情况:

"

ThethethemeofthisarticleistheJava'

sregexpackage."

,这一点在regex中能非常简单地实现,即通过使用在Pattern类中预定义的静态标志CASE_INSENSITIVE:

  Patternpattern=Ppile("

  Pattern.CASE_INSENSITIVE);

  有关正则表达式的话题是非常丰富,而且复杂的,用Java来实现也非常广泛,则需要对regex包进行的彻底研究,我们在这里所讲的只是冰山一角。

即使你对正则表达式比较陌生,使用regex包后会很快发现它强大功能和可伸缩性。

如果你是个来自Perl或其他语言王国的老练的正则表达式的黑客,使用过regex包后,你将会安心地投入到java的世界,而放弃其他的工具,并把java的regex包看成是手边必备的利器。

CharSequence

JDK1.4定义了一个新的接口,叫CharSequence。

它提供了String和StringBuffer这两个类的字符序列的抽象:

interfaceCharSequence{

charAt(inti);

length();

subSequence(intstart,intend);

toString();

}

为了实现这个新的CharSequence接口,String,StringBuffer以及CharBuffer都作了修改。

很多正则表达式的操作都要拿CharSequence作参数。

Pattern和Matcher

先给一个例子。

下面这段程序可以测试正则表达式是否匹配字符串。

第一个参数是要匹配的字符串,后面是正则表达式。

正则表达式可以有多个。

在Unix/Linux环境下,命令行下的正则表达式还必须用引号。

//:

c12:

TestRegularExpression.java

//Allowsyoutoeaslytryoutregularexpressions.

//{Args:

abcabcabcdefabc"

abc+"

"

(abc)+"

(abc){2,}"

}

importjava.util.regex.*;

publicclassTestRegularExpression{

publicstaticvoidmain(String[]args){

if(args.length<

2){

System.out.println("

Usage:

/n"

+

javaTestRegularExpression"

characterSequenceregularExpression+"

System.exit(0);

Input:

/"

+args[0]+"

/"

for(inti=1;

i<

args.length;

i++){

System.out.println(

Regularexpression:

+args[i]+"

Patternp=Ppile(args[i]);

Matcherm=p.matcher(args[0]);

while(m.find()){

Match/"

+m.group()+

atpositions"

m.start()+"

-"

+(m.end()-1));

}///:

~

Java的正则表达式是由java.util.regex的Pattern和Matcher类实现的。

Pattern对象表示经编译的正则表达式。

静态的compile()方法负责将表示正则表达式的字符串编译成Pattern对象。

正如上述例程所示的,只要给Pattern的matcher()方法送一个字符串就能获取一个Matcher对象。

此外,Pattern还有一个能快速判断能否在input里面找到regex的

staticbooleanmatches(?

regex,?

input)

以及能返回String数组的split()方法,它能用regex把字符串分割开来。

只要给Pattern.matcher()方法传一个字符串就能获得Matcher对象了。

接下来就能用Matcher的方法来查询匹配的结果了。

booleanmatches()

booleanlookingAt()

booleanfind()

booleanfind(intstart)

matches()的前提是Pattern匹配整个字符串,而lookingAt()的意思是Pattern匹配字符串的开头。

find()

Matcher.find()的功能是发现CharSequence里的,与pattern相匹配的多个字符序列。

例如:

FindDemo.java

importcom.bruceeckel.simpletest.*;

importjava.util.*;

publicclassFindDemo{

privatestaticTestmonitor=newTest();

Matcherm=Ppile("

//w+"

.matcher("

Eveningisfullofthelinnet'

swings"

while(m.find())

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

inti=0;

while(m.find(i)){

System.out.print(m.group()+"

i++;

monitor.expect(newString[]{

Evening"

is"

full"

of"

the"

linnet"

s"

wings"

Eveningveningeningningingnggisissfull"

fullulllllofoffthetheheelinnetlinnet"

innetnnetnetettsswingswingsingsngsgss"

});

的意思是"

一个或多个单词字符"

,因此它会将字符串直接分解成单词。

find()像一个迭代器,从头到尾扫描一遍字符串。

第二个find()是带int参数的,正如你所看到的,它会告诉方法从哪里开始找——即从参数位置开始查找。

Groups

Group是指里用括号括起来的,能被后面的表达式调用的正则表达式。

Group0表示整个表达式,group1表示第一个被括起来的group,以此类推。

所以;

A(B(C))D

里面有三个group:

group0是ABCD,group1是BC,group2是C。

你可以用下述Matcher方法来使用group:

publicintgroupCount()返回matcher对象中的group的数目。

不包括group0。

publicStringgroup()返回上次匹配操作(比方说find())的group0(整个匹配)

publicStringgroup(inti)返回上次匹配操作的某个group。

如果匹配成功,但是没能找到group,则返回null。

publicintstart(intgroup)返回上次匹配所找到的,group的开始位置。

publicintend(intgroup)返回上次匹配所找到的,group的结束位置,最后一个字符的下标加一。

Groups.java

publicclassGroups{

staticpublicfinalStringpoem=

Twasbrillig,andtheslithytoves/n"

Didgyreandgimbleinthewabe./n"

Allmimsyweretheborogoves,/n"

Andthemomerathsoutgrabe./n/n"

BewaretheJabberwock,myson,/n"

Thejawsthatbite,theclawsthatcatch./n"

BewaretheJubjubbird,andshun/n"

ThefrumiousBandersnatch."

;

Matcherm=

Ppile("

(?

m)(//S+)//s+((//S+)//s+(//S+))___FCKpd___6quot;

.matcher(poem);

for(intj=0;

j<

=m.groupCount();

j++)

System.out.print("

["

+m.group(j)+"

]"

System.out.println();

monitor.expect(newString[]{

[theslithytoves]"

[the][slithytoves][slithy][toves]"

[inthewabe.][in][thewabe.][the][wabe.]"

[weretheborogoves,]"

[were][theborogoves,][the][borogoves,]"

[momerathsoutgrabe.]"

[mome][rathsoutgrabe.][raths][outgrabe.]"

[Jabberwock,myson,]"

[Jabberwock,][myson,][my][son,]"

[clawsthatcatch.]"

[claws][thatcatch.][that][catch.]"

[bird,andshun][bird,][andshun][and][shun]"

[ThefrumiousBandersnatch.][The]"

[frumiousBandersnatch.][frumious][Bandersnatch.]"

这首诗是ThroughtheLookingGlass的,LewisCarroll的"

Jabberwocky"

的第一部分。

可以看到这个正则表达式里有很多用括号括起来的group,它是由任意多个连续的非空字符('

/S+'

)和任意多个连续的空格字符('

/s+'

)所组成的,其最终目的是要捕获每行的最后三个单词;

'

$'

表示一行的结尾。

但是'

通常表示整个字符串的结尾,所以这里要明确地告诉正则表达式注意换行符。

这一点是由'

m)'

标志完成的(模式标志会过一会讲解)。

start()和end()

如果匹配成功,start()会返回此次匹配的开始位置,end()会返回此次匹配的结束位置,即最后一个字符的下标加一。

如果之前的匹配不成功(或者没匹配),那么无论是调用start()还是end(),都会引发一个IllegalStateException。

下面这段程序还演示了matches()和lookingAt():

StartEnd.java

publicclassStartEnd{

String[]input=newString[]{

Javahasregularexpressionsin1.4"

regularexpressionsnowexpressinginJava"

Javarepressesoracularexpressions"

};

Pattern

p1=Ppile("

re//w*"

),

p2=Ppile("

Java.*"

for(inti=0;

input.length;

input"

+i+"

:

+input[i]);

Matcher

m1=p1.matcher(input[i]),

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1