ImageVerifierCode 换一换
格式:DOCX , 页数:34 ,大小:237.20KB ,
资源ID:12119197      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12119197.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Java正则表达式详解.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Java正则表达式详解.docx

1、Java正则表达式详解在Sun的Java JDK 1.40版本中,Java自带了支持正则表达式的包,本文就抛砖引玉地介绍了如何使用java.util.regex包。可粗略估计一下,除了偶尔用Linux的外,其他Linu x用户都会遇到正则表达式。正则表达式是个极端强大工具,而且在字符串模式-匹配和字符串模式-替换方面富有弹性。在Unix世界里,正则表达式几乎没有什么限制,可肯定的是,它应用非常之广泛。正则表达式的引擎已被许多普通的Unix工具所实现,包括grep,awk,vi和Emacs等。此外,许多使用比较广泛的脚本语言也支持正则表达式,比如Python,Tcl,JavaScript,以及最

2、著名的Perl。我很早以前就是个Perl方面的黑客,如果你和我一样话,你也会非常依赖你手边的这些强大的text-munging工具。近几年来,像其他程序开发者一样,我也越来越关注Java的开发。Java作为一种开发语言,有许多值得推荐的地方,但是它一直以来没有自带对正则表达式的支持。直到最近,借助于第三方的类库,Java开始支持正则表达式,但这些第三方的类库都不一致、兼容性差,而且维护代码起来很糟糕。这个缺点,对我选择Java作为首要的开发工具来说,一直是个巨大的顾虑之处。你可以想象,当我知道Sun的Java JDK 1.40版本包含了java.util.regex(一个完全开放、自带的正则表

3、达式包)时,是多么的高兴!很搞笑的说,我花好些时间去挖掘这个被隐藏起来的宝石。我非常惊奇的是,Java这样的一个很大改进(自带了java.util.regex包)为什么不多公开一点呢?!最近,Java双脚都跳进了正则表达式的世界。java.util.regex包在支持正则表达也有它的过人之处,另外Java也提供详细的相关说明文档。使得朦朦胧胧的regex神秘景象也慢慢被拨开。有一些正则表达式的构成(可能最显著的是,在于糅合了字符类库)在Perl都找不到。在regex包中,包括了两个类,Pattern(模式类)和Matcher(匹配器类)。Pattern类是用来表达和陈述所要搜索模式的对象,Ma

4、tcher类是真正影响搜索的对象。另加一个新的例外类,PatternSyntaxException,当遇到不合法的搜索模式时,会抛出例外。即使对正则表达式很熟悉,你会发现,通过java使用正则表达式也相当简单。要说明的一点是,对那些被Perl的单行匹配所宠坏的Perl狂热爱好者来说,在使用java的regex包进行替换操作时,会比他们所以前常用的方法费事些。本文的局限之处,它不是一篇正则表达式用法的完全教程。如果读者要对正则表达进一步了解的话,推荐阅读Jeffrey Frieldl的Mastering Regular Expressions,该书由OReilly出版社出版。我下面就举一些例子来

5、教读者如何使用正则表达式,以及如何更简单地去使用它。设计一个简单的表达式来匹配任何电话号码数字可能是比较复杂的事情,原因在于电话号码格式有很多种情况。所有必须选择一个比较有效的模式。比如:(212) 555-1212, 212-555-1212和212 555 1212,某些人会认为它们都是等价的。首先让我们构成一个正则表达式。为简单起见,先构成一个正则表达式来识别下面格式的电话号码数字:(nnn)nnn-nnnn。第一步,创建一个pattern对象来匹配上面的子字符串。一旦程序运行后,如果需要的话,可以让这个对象一般化。匹配上面格式的正则表达可以这样构成:(d3)sd3-d4,其中d单字符类

6、型用来匹配从0到9的任何数字,另外3重复符号,是个简便的记号,用来表示有3个连续的数字位,也等效于(ddd)。s也另外一个比较有用的单字符类型,用来匹配空格,比如Space键,tab键和换行符。是不是很简单?但是,如果把这个正则表达式的模式用在java程序中,还要做两件事。对java的解释器来说,在反斜线字符()前的字符有特殊的含义。在java中,与regex有关的包,并不都能理解和识别反斜线字符(),尽管可以试试看。但为避免这一点,即为了让反斜线字符()在模式对象中被完全地传递,应该用双反斜线字符()。此外圆括号在正则表达中两层含义,如果想让它解释为字面上意思(即圆括号),也需要在它前面用双

7、反斜线字符()。也就是像下面的一样:(d3)sd3-d4现在介绍怎样在java代码中实现刚才所讲的正则表达式。要记住的事,在用正则表达式的包时,在你所定义的类前需要包含该包,也就是这样的一行:import java.util.regex.*;下面的一段代码实现的功能是,从一个文本文件逐行读入,并逐行搜索电话号码数字,一旦找到所匹配的,然后输出在控制台。BufferedReader in;Pattern pattern = Ppile(d3)sd3-d4);in = new BufferedReader(new FileReader(phone);String s;while (s = in.r

8、eadLine() != null)Matcher matcher = pattern.matcher(s);if (matcher.find()System.out.println(matcher.group();in.close();对那些熟悉用Python或Javascript来实现正则表达式的人来说,这段代码很平常。在Python和Javascript这些语言中,或者其他的语言,这些正则表达式一旦明确地编译过后,你想用到哪里都可以。与Perl的单步匹配相比,看起来多多做了些工作,但这并不很费事。find()方法,就像你所想象的,用来搜索与正则表达式相匹配的任何目标字符串,group()

9、方法,用来返回包含了所匹配文本的字符串。应注意的是,上面的代码,仅用在每行只能含有一个匹配的电话号码数字字符串时。可以肯定的说,java的正则表达式包能用在一行含有多个匹配目标时的搜索。本文的原意在于举一些简单的例子来激起读者进一步去学习java自带的正则表达式包,所以对此就没有进行深入的探讨。这相当漂亮吧! 但是很遗憾的是,这仅是个电话号码匹配器。很明显,还有两点可以改进。如果在电话号码的开头,即区位号和本地号码之间可能会有空格。我们也可匹配这些情况,则通过在正则表达式中加入s?来实现,其中?元字符表示在模式可能有0或1个空格符。第二点是,在本地号码位的前三位和后四位数字间有可能是空格符,而

10、不是连字号,更有胜者,或根本就没有分隔符,就是7位数字连在一起。对这几种情况,我们可以用(-|)?来解决。这个结构的正则表达式就是转换器,它能匹配上面所说的几种情况。在()能含有管道符|时,它能匹配是否含有空格符或连字符,而尾部的?元字符表示是否根本没有分隔符的情况。最后,区位号也可能没有包含在圆括号内,对此可以简单地在圆括号后附上?元字符,但这不是一个很好的解决方法。因为它也包含了不配对的圆括号,比如(555 或 555)。相反,我们可以通过另一种转换器来强迫让电话号码是否带有有圆括号:(d3)|d3)。如果我们把上面代码中的正则表达式用这些改进后的来替换的话,上面的代码就成了一个非常有用的

11、电话号码数字匹配器:Pattern pattern =Ppile(d3)|d3)s?d3(-|)?d4);可以确定的是,你可以自己试着进一步改进上面的代码。现在看看第二个例子,它是从Friedl的中改编过来的。其功能是用来检查文本文件中是否有重复的单词,这在印刷排版中会经常遇到,同样也是个语法检查器的问题。匹配单词,像其他的一样,也可以通过好几种的正则表达式来完成。可能最直接的是bw+b,其优点在于只需用少量的regex元字符。其中w元字符用来匹配从字母a到u的任何字符。+元字符表示匹配匹配一次或多次字符,b元字符是用来说明匹配单词的边界,它可以是空格或任何一种不同的标点符号(包括逗号,句号等

12、)。现在,我们怎样来检查一个给定的单词是否被重复了三次?为完成这个任务,需充分利用正则表达式中的所熟知的向后扫描。如前面提到的,圆括号在正则表达式中有几种不同的用法,一个就是能提供组合类型,组合类型用来保存所匹配的结果或部分匹配的结果(以便后面能用到),即使遇到有相同的模式。在同样的正则表达中,可能(也通常期望)不止有一个组合类型。在第n个组合类型中匹配结果可以通过向后扫描来获取到。向后扫描使得搜索重复的单词非常简单:b(w+)s+1b。圆括号形成了一个组合类型,在这个正则表示中它是第一组合类型(也是仅有的一个)。向后扫描1,指的是任何被w+所匹配的单词。我们的正则表达式因此能匹配这样的单词,

13、它有一个或多个空格符,后面还跟有一个与此相同的单词。注意的是,尾部的定位类型(b)必不可少,它可以防止发生错误。如果我们想匹配Paris in the the spring,而不是匹配Javas regex package is the theme of this article。根据java现在的格式,则上面的正则表达式就是:Pattern pattern =Ppile(b(w+)s+1b);最后进一步的修改是让我们的匹配器对大小写敏感。比如,下面的情况:The the theme of this article is the Javas regex package.,这一点在regex中能

14、非常简单地实现,即通过使用在Pattern类中预定义的静态标志CASE_INSENSITIVE :Pattern pattern =Ppile(b(w+)s+1b,Pattern.CASE_INSENSITIVE);有关正则表达式的话题是非常丰富,而且复杂的,用Java来实现也非常广泛,则需要对regex包进行的彻底研究,我们在这里所讲的只是冰山一角。即使你对正则表达式比较陌生,使用regex包后会很快发现它强大功能和可伸缩性。如果你是个来自Perl或其他语言王国的老练的正则表达式的黑客,使用过regex包后,你将会安心地投入到java的世界,而放弃其他的工具,并把java的regex包看成是

15、手边必备的利器。 CharSequenceJDK 1.4定义了一个新的接口,叫CharSequence。它提供了String和StringBuffer这两个类的字符序列的抽象:interface CharSequence charAt(int i); length(); subSequence(int start, int end); toString();为了实现这个新的CharSequence接口,String,StringBuffer以及CharBuffer都作了修改。很多正则表达式的操作都要拿CharSequence作参数。Pattern和Matcher先给一个例子。下面这段程序可以测

16、试正则表达式是否匹配字符串。第一个参数是要匹配的字符串,后面是正则表达式。正则表达式可以有多个。在Unix/Linux环境下,命令行下的正则表达式还必须用引号。/: c12:TestRegularExpression.java/ Allows you to easly try out regular expressions./ Args: abcabcabcdefabc abc+ (abc)+ (abc)2, import java.util.regex.*;publicclass TestRegularExpression publicstaticvoid main(String args)

17、 if(args.length 2) System.out.println(Usage:n +java TestRegularExpression +characterSequence regularExpression+); System.exit(0); System.out.println(Input: + args0 + );for(int i = 1; i args.length; i+) System.out.println(Regular expression: + argsi + ); Pattern p = Ppile(argsi); Matcher m = p.matche

18、r(args0);while(m.find() System.out.println(Match + m.group() + at positions + m.start() + - + (m.end() - 1); /: Java的正则表达式是由java.util.regex的Pattern和Matcher类实现的。Pattern对象表示经编译的正则表达式。静态的compile( )方法负责将表示正则表达式的字符串编译成Pattern对象。正如上述例程所示的,只要给Pattern的matcher( )方法送一个字符串就能获取一个Matcher对象。此外,Pattern还有一个能快速判断能否在

19、input里面找到regex的staticboolean matches(?regex, ?input)以及能返回String数组的split( )方法,它能用regex把字符串分割开来。只要给Pattern.matcher( )方法传一个字符串就能获得Matcher对象了。接下来就能用Matcher的方法来查询匹配的结果了。boolean matches()boolean lookingAt()boolean find()boolean find(int start)matches( )的前提是Pattern匹配整个字符串,而lookingAt( )的意思是Pattern匹配字符串的开头。

20、find( )Matcher.find( )的功能是发现CharSequence里的,与pattern相匹配的多个字符序列。例如:/: c12:FindDemo.javaimport java.util.regex.*;import com.bruceeckel.simpletest.*;import java.util.*;publicclass FindDemo privatestatic Test monitor = new Test();publicstaticvoid main(String args) Matcher m = Ppile(w+) .matcher(Evening i

21、s full of the linnets wings);while(m.find() System.out.println(m.group();int i = 0;while(m.find(i) System.out.print(m.group() + ); i+; monitor.expect(new String Evening,is,full,of,the,linnet,s,wings,Evening vening ening ning ing ng g is is s full +full ull ll l of of f the the he e linnet linnet +in

22、net nnet net et t s s wings wings ings ngs gs s ); /: w+的意思是一个或多个单词字符,因此它会将字符串直接分解成单词。find( )像一个迭代器,从头到尾扫描一遍字符串。第二个find( )是带int参数的,正如你所看到的,它会告诉方法从哪里开始找即从参数位置开始查找。GroupsGroup是指里用括号括起来的,能被后面的表达式调用的正则表达式。Group 0 表示整个表达式,group 1表示第一个被括起来的group,以此类推。所以;A(B(C)D里面有三个group:group 0是ABCD, group 1是BC,group 2是C

23、。你可以用下述Matcher方法来使用group:public int groupCount( )返回matcher对象中的group的数目。不包括group0。public String group( ) 返回上次匹配操作(比方说find( )的group 0(整个匹配)public String group(int i)返回上次匹配操作的某个group。如果匹配成功,但是没能找到group,则返回null。public int start(int group)返回上次匹配所找到的,group的开始位置。public int end(int group)返回上次匹配所找到的,group的结束

24、位置,最后一个字符的下标加一。/: c12:Groups.javaimport java.util.regex.*;import com.bruceeckel.simpletest.*;publicclass Groups privatestatic Test monitor = new Test();staticpublicfinal String poem =Twas brillig, and the slithy tovesn +Did gyre and gimble in the wabe.n +All mimsy were the borogoves,n +And the mome

25、raths outgrabe.nn +Beware the Jabberwock, my son,n +The jaws that bite, the claws that catch.n +Beware the Jubjub bird, and shunn +The frumious Bandersnatch.;publicstaticvoid main(String args) Matcher m = Ppile(?m)(S+)s+(S+)s+(S+)_FCKpd_6quot;) .matcher(poem);while(m.find() for(int j = 0; j = m.grou

26、pCount(); j+) System.out.print( + m.group(j) + ); System.out.println(); monitor.expect(new Stringthe slithy toves +theslithy tovesslithytoves,in the wabe.inthe wabe.thewabe.,were the borogoves, +werethe borogoves,theborogoves,mome raths outgrabe. +momeraths outgrabe.rathsoutgrabe.,Jabberwock, my son

27、, +Jabberwock,my son,myson,claws that catch. +clawsthat catch.thatcatch.,bird, and shunbird,and shunandshun,The frumious Bandersnatch.The +frumious Bandersnatch.frumiousBandersnatch. ); /: 这首诗是Through the Looking Glass的,Lewis Carroll的Jabberwocky的第一部分。可以看到这个正则表达式里有很多用括号括起来的group,它是由任意多个连续的非空字符(S+)和任意

28、多个连续的空格字符(s+)所组成的,其最终目的是要捕获每行的最后三个单词;$表示一行的结尾。但是$通常表示整个字符串的结尾,所以这里要明确地告诉正则表达式注意换行符。这一点是由(?m)标志完成的(模式标志会过一会讲解)。start( )和end( )如果匹配成功,start( )会返回此次匹配的开始位置,end( )会返回此次匹配的结束位置,即最后一个字符的下标加一。如果之前的匹配不成功(或者没匹配),那么无论是调用start( )还是end( ),都会引发一个IllegalStateException。下面这段程序还演示了matches( )和lookingAt( ):/: c12:Star

29、tEnd.javaimport java.util.regex.*;import com.bruceeckel.simpletest.*;publicclass StartEnd privatestatic Test monitor = new Test();publicstaticvoid main(String args) String input = new String Java has regular expressions in 1.4,regular expressions now expressing in Java,Java represses oracular expres

30、sions ; Pattern p1 = Ppile(rew*), p2 = Ppile(Java.*);for(int i = 0; i input.length; i+) System.out.println(input + i + : + inputi); Matcher m1 = p1.matcher(inputi), m2 = p2.matcher(inputi);while(m1.find() System.out.println(m1.find() + m1.group() + start = + m1.start() + end = + m1.end();while(m2.find() System.out.println(m2.find() + m2.group() + start = + m2.start() + end = + m2.end(

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

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