java正则表达式详解.doc
在Sun的JavaJDK1.40版本中,Java自带了支持正那么表达式的包,本文就抛砖引玉地介绍了如何使用java.util.regex包。
可粗略估计一下,除了偶尔用Linux的外,其他Linux用户都会遇到正那么表达式。正那么表达式是个极端强大工具,而且在字符串模式-匹配和字符串模式-替换方面富有弹性。在Unix世界里,正那么表达式几乎没有什么限制,可肯定的是,它应用非常之广泛。
正那么表达式的引擎已被许多普通的Unix工具所实现,包括grep,awk,vi和Emacs等。此外,许多使用比拟广泛的脚本语言也支持正那么表达式,比方Python,Tcl,JavaScript,以及最著名的Perl。
我很早以前就是个Perl方面的黑客,如果你和我一样话,你也会非常依赖你手边的这些强大的text-munging工具。近几年来,像其他程序开发者一样,我也越来越关注Java的开发。
Java作为一种开发语言,有许多值得推荐的地方,但是它一直以来没有自带对正那么表达式的支持。直到最近,借助于第三方的类库,Java开始支持正那么表达式,但这些第三方的类库都不一致、兼容性差,而且维护代码起来很糟糕。这个缺点,对我选择Java作为首要的开发工具来说,一直是个巨大的顾虑之处。
你可以想象,当我知道Sun的JavaJDK1.40版本包含了java.util.regex(一个完全开放、自带的正那么表达式包)时,是多么的快乐!很搞笑的说,我花好些时间去挖掘这个被隐藏起来的宝石。我非常惊奇的是,Java这样的一个很大改良(自带了java.util.regex包)为什么不多公开一点呢?!
最近,Java双脚都跳进了正那么表达式的世界。java.util.regex包在支持正那么表达也有它的过人之处,另外Java也提供详细的相关说明文档。使得朦朦胧胧的regex神秘景象也慢慢被拨开。有一些正那么表达式的构成(可能最显著的是,在于糅合了字符类库)在Perl都找不到。
在regex包中,包括了两个类,Pattern(模式类)和Matcher(匹配器类)。Pattern类是用来表达和陈述所要搜索模式的对象,Matcher类是真正影响搜索的对象。另加一个新的例外类,PatternSyntaxException,当遇到不合法的搜索模式时,会抛出例外。
即使对正那么表达式很熟悉,你会发现,通过java使用正那么表达式也相当简单。要说明的一点是,对那些被Perl的单行匹配所宠坏的Perl狂热爱好者来说,在使用java的regex包进行替换操作时,会比他们所以前常用的方法费事些。
本文的局限之处,它不是一篇正那么表达式用法的完全教程。如果读者要对正那么表达进一步了解的话,推荐阅读JeffreyFrieldl的MasteringRegularExpressions,该书由O’Reilly出版社出版。我下面就举一些例子来教读者如何使用正那么表达式,以及如何更简单地去使用它。
设计一个简单的表达式来匹配任何号码数字可能是比拟复杂的事情,原因在于号码格式有很多种情况。所有必须选择一个比拟有效的模式。比方:(212)555-1212,212-555-1212和2125551212,某些人会认为它们都是等价的。
首先让我们构成一个正那么表达式。为简单起见,先构成一个正那么表达式来识别下面格式的号码数字:(nnn)nnn-nnnn。
第一步,创立一个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代码中实现刚刚所讲的正那么表达式。要记住的事,在用正那么表达式的包时,在你所定义的类前需要包含该包,也就是这样的一行: