前往顾页
以后地位: 主页 > 收集编程 > Jsp实例教程 >

Java正则表达式详解

时候:2015-06-30 08:55来源:知行网www.zhixing123.cn 编辑:麦田守望者
如果你曾用过Perl或任何其他内建正则表达式支撑的说话,你必然晓得用正则表达式措置文本和婚配形式是多么简朴。
 
 
如果你不熟谙这个术语,那么“正则表达式”(Regular Expression)就是一个字符构成的串,它定义了一个用来搜刮婚配字符串的形式。

 

正则表达式30分钟入门教程

常常利用正则表达式

很多说话,包含Perl、PHP、Python、JavaScript和JScript,都支撑用正则表达式措置文本,一些文本编辑器用正则表达式实现高级“搜刮-替代”服从。那么Java又怎样呢?本文写作时,一个包含了用正则表达式进行文本措置的Java标准需求(Specification Request)已获得承认,你可以等候在JDK的下一版本中看到它。
但是,如果现在就需求利用正则表达式,又该怎样办呢?你可以从Apache.org下载源代码开放的Jakarta-ORO库。本文接上去的内容先扼要地介绍正则表达式的入门知识,然后以Jakarta-ORO API为例介绍若何利用正则表达式。
一、正则表达式根本知识

 

 

我们先从简朴的开端。假定你要搜刮一个包含字符“cat”的字符串,搜刮用的正则表达式就是“cat”。如果搜刮对年夜小写不敏感,单词“catalog”、“Catherine”、“sophisticated”都可以婚配。也就是说:
1.1 句点标记
假定你在玩英文拼字游戏,想要找出三个字母的单词,并且这些单词必须以“t”字母开首,以“n”字母结束。别的,假定有一本英笔墨典,你可以用正则表达式搜刮它的全数内容。要机关出这个正则表达式,你可利用一个通配符——句点标记“.”。如许,完整的表达式就是“t.n”,它婚配“tan”、“ten”、“tin”和“ton”,还婚配“t#n”、“tpn”乃至“t n”,另有其他很多无意义的组合。这是因为句点标记婚配所有字符,包含空格、Tab字符乃至换行符:
1.2 方括号标记
为体味决句点标记婚配范围过于遍及这一问题,你可以在方括号(“[]”)内里指定看来成心义的字符。此时,只需方括号内里指定的字符才参与婚配。也就是说,正则表达式“t[aeio]n”只婚配“tan”、“Ten”、“tin”和“ton”。但“Toon”不婚配,因为在方括号以内你只能婚配单个字符:
1.3 “或”标记
如果除下面婚配的所有单词以外,你还想要婚配“toon”,那么,你可利用“|”操纵符。“|”操纵符的根基意义就是“或”运算。要婚配“toon”,利用“t(a|e|i|o|oo)n”正则表达式。这里不克不及利用方扩号,因为方括号只许可婚配单个字符;这里必须利用圆括号“()”。圆括号还可以用来分组,详细请拜见前面介绍。
1.4 表示婚配次数的标记
表一显现了表示婚配次数的标记,这些标记用来肯定紧靠该标记左边的标记呈现的次数:

假定我们要在文本文件中搜刮美国的社会宁静号码。这个号码的格局是999-99-9999。用来婚配它的正则表达式如图一所示。在正则表达式中,连字符(“-”)有着特别的意义,它表示一个范围,比如从0到9。是以,婚配社会宁静号码中的连字标记时,它的前面要加上一个转义字符“”。

图一:婚配所有123-12-1234情势的社会宁静号码

假定进行搜刮的时候,你希望连字标记可以呈现,也能够不呈现——即,999-99-9999和999999999都属于精确的格局。这时候,你可以在连字标记前面加上“?”数量限定标记,如图二所示:

图二:婚配所有123-12-1234和123121234情势的社会宁静号码

下面我们再来看别的一个例子。美国汽车牌照的一种格局是四个数字加上二个字母。它的正则表达式前面是数字部分“[0-9]{4}”,再加上字母部分“[A-Z]{2}”。图三显现了完整的正则表达式。

图三:婚配典范的美国汽车牌照号码,如8836KV

1.5 “否”标记
“^”标记称为“否”标记。如果用在方括号内,“^”表示不想要婚配的字符。比方,图四的正则表达式婚配所有单词,但以“X”字母开首的单词除外。

图四:婚配所有单词,但“X”开首的除外

1.6 圆括号和空缺标记
假定要从格局为“June 26, 1951”的华诞日期中提取出月份部分,用来婚配该日期的正则表达式可以如图五所示:

图五:婚配所有Moth DD,YYYY格局的日期

新呈现的“s”标记是空缺标记,婚配所有的空缺字符,包含Tab字符。如果字符串精确婚配,接上去若何提取出月份部分呢?只需在月份四周加上一个圆括号建立一个组,然后用ORO API(本文前面详细会商)提取出它的值。点窜后的正则表达式如图六所示:

图六:婚配所有Month DD,YYYY格局的日期,定义月份值为第一个组

1.7 别的标记
为简练起见,你可利用一些为常见正则表达式建立的疾速标记。如表二所示:
表二:常常利用标记

比方,在前面社会宁静号码的例子中,所有呈现“[0-9]”的处所我们都可利用“d”。点窜后的正则表达式如图七所示:

图七:婚配所有123-12-1234格局的社会宁静号码

2、Jakarta-ORO库
有很多源代码开放的正则表达式库可供Java法度员利用,并且它们中的很多支撑Perl 5兼容的正则表达式语法。我在这里选用的是Jakarta-ORO正则表达式库,它是最全面的正则表达式API之一,并且它与Perl 5正则表达式完整兼容。别的,它也是优化得最好的API之一。
Jakarta-ORO库之前叫做OROMatcher,Daniel Savarese年夜方地把它赠送给了Jakarta Project。你可以遵循本文最后参考资本的申明下载它。
我起首将扼要介绍利用Jakarta-ORO库时你必须建立和拜候的工具,然后介绍若何利用Jakarta-ORO API。
▲ PatternCompiler工具
起首,建立一个Perl5Compiler类的实例,并把它赋值给PatternCompiler接口工具。Perl5Compiler是PatternCompiler接口的一个实现,许可你把正则表达式编译成用来婚配的Pattern工具。
▲ Pattern工具
要把正则表达式编译成Pattern工具,调用compiler工具的compile()体例,并在调用参数中指定正则表达式。比方,你可以遵循下面这类体例编译正则表达式“t[aeio]n”:
默许环境下,编译器建立一个年夜小写敏感的形式(pattern)。是以,下面代码编译获得的形式只婚配“tin”、“tan”、 “ten”和“ton”,但不婚配“Tin”和“taN”。要建立一个年夜小写不敏感的形式,你应当在调用编译器的时候指定一个分外的参数:
建立好Pattern工具以后,你便可以经由过程PatternMatcher类用该Pattern工具进行形式婚配。
▲ PatternMatcher工具
PatternMatcher工具按照Pattern工具和字符串进行婚配查抄。你要实例化一个Perl5Matcher类并把成果赋值给PatternMatcher接口。Perl5Matcher类是PatternMatcher接口的一个实现,它按照Perl 5正则表达式语法进行形式婚配:
利用PatternMatcher工具,你可以用多个别例进行婚配操纵,这些体例的第一个参数都是需求按照正则表达式进行婚配的字符串:
· boolean matches(String input, Pattern pattern):当输入字符串和正则表达式要切确婚配时利用。换句话说,正则表达式必须完整地描述输入字符串。
· boolean matchesPrefix(String input, Pattern pattern):当正则表达式婚配输入字符串肇端部分时利用。
· boolean contains(String input, Pattern pattern):当正则表达式要婚配输入字符串的一部分时利用(即,它必须是一个子串)。
别的,在下面三个别例调用中,你还可以用PatternMatcherInput工具作为参数替代String工具;这时候,你可以从字符串中最后一次婚配的地位开端继续进行婚配。当字符串可能有多个子串婚配给定的正则表达式时,用PatternMatcherInput工具作为参数就很有效了。用PatternMatcherInput工具作为参数替代String时,上述三个别例的语法以下:
· boolean matches(PatternMatcherInput input, Pattern pattern)
· boolean matchesPrefix(PatternMatcherInput input, Pattern pattern)
· boolean contains(PatternMatcherInput input, Pattern pattern)
3、利用实例
下面我们来看看Jakarta-ORO库的一些利用实例。
3.1 日记文件措置
任务:阐发一个Web办事器日记文件,肯定每个用户花在网站上的时候。在典范的BEA WebLogic日记文件中,日记记录的格局以下:
阐发这个日记记录,可以发明,要从这个日记文件提取的内容有两项:IP地点和页面拜候时候。你可以用分组标记(圆括号)从日记记录提取出IP地点和时候标识表记标帜。
起首我们来看看IP地点。IP地点有4个字节构成,每个字节的值在0到255之间,各个字节经由过程一个句点分开。是以,IP地点中的每个字节有起码一个、最多三个数字。图八显现了为IP地点编写的正则表达式:

图八:婚配IP地点

IP地点中的句点字符必须进行转义措置(前面加上“”),因为IP地点中的句点具有它原本的含义,而不是采取正则表达式语法中的特别含义。句点在正则表达式中的特别含义本文前面已介绍。
日记记录的时候部分由一对方括号包抄。你可以遵循以下思路提取出方括号内里的所有内容:起首搜刮肇端方括号字符(“[”),提取出所有不超越结束方括号字符(“]”)的内容,向前寻觅直至找到结束方括号字符。图九显现了这部分的正则表达式。

图九:婚配起码一个字符,直至找到“]”

现在,把上述两个正则表达式加上分组标记(圆括号)后归并成单个表达式,如许便可以从日记记录提取出IP地点和时候。重视,为了婚配“- -”(但不提取它),正则表达式中间插手了“s-s-s”。完整的正则表达式如图十所示。

图十:婚配IP地点和时候标识表记标帜

现在正则表达式已编写结束,接上去可以编写利用正则表达式库的Java代码了。
为利用Jakarta-ORO库,起首建立正则表达式字符串和待阐发的日记记录字符串:
这里利用的正则表达式与图十的正则表达式差不多完整不异,但有一点例外:在Java中,你必须对每个向前的斜杠(“”)进行转义措置。图十不是Java的表示情势,所以我们要在每个“”前面加上一个“”以避免呈现编译错误。遗憾的是,转义措置过程很容易呈现错误,所以应当小心谨慎。你可以起首输入未经转义措置的正则表达式,然后从左到右顺次把每个“”替代成“\”。如果要复检,你可以试着把它输入到屏幕上。
初始化字符串以后,实例化PatternCompiler工具,用PatternCompiler编译正则表达式建立一个Pattern工具:
现在,建立PatternMatcher工具,调用PatternMatcher接口的contain()体例查抄婚配环境:
接上去,操纵PatternMatcher接口前往的MatchResult工具,输入婚配的组。因为logEntry字符串包含婚配的内容,你可以看到类以下面的输入:
3.2 HTML措置实例一
下面一个任务是阐发HTML页面内FONT标识表记标帜的所有属性。HTML页面内典范的FONT标识表记标帜以下所示:
法度将遵循以下情势,输入每个FONT标识表记标帜的属性:
在这类环境下,我建议你利用两个正则表达式。第一个如图十一所示,它从字体标识表记标帜提取出“"face="Arial, Serif" size="+2" color="red"”。

图十一:婚配FONT标识表记标帜的所有属性

第二个正则表达式如图十二所示,它把各个属性豆割成名字-值对。

图十二:婚配单个属性,并把它豆割成名字-值对

豆割成果为:
现在我们来看看完成这个任务的Java代码。起首建立两个正则表达式字符串,用Perl5Compiler把它们编译成Pattern工具。编译正则表达式的时候,指定Perl5Compiler.CASE_INSENSITIVE_MASK选项,使得婚配操纵不辨别年夜小写。
接上去,建立一个履行婚配操纵的Perl5Matcher工具。
假定有一个String范例的变量html,它代表了HTML文件中的一行内容。如果html字符串包含FONT标识表记标帜,婚配器将前往true。此时,你可以用婚配器工具前往的MatchResult工具获得第一个组,它包含了FONT的所有属性:
接上去建立一个PatternMatcherInput工具。这个工具许可你从最后一次婚配的地位开端继续进行婚配操纵,是以,它很适合于提取FONT标识表记标帜内属性的名字-值对。建立PatternMatcherInput工具,以参数情势传入待婚配的字符串。然后,用婚配器实例提取出每个FONT的属性。这经由过程指定PatternMatcherInput工具(而不是字符串工具)为参数,几次地调用PatternMatcher工具的contains()体例完成。PatternMatcherInput工具当中的每次迭代将把它外部的指针向前挪动,下一次检测将畴前一次婚配地位的前面开端。
本例的输入成果以下:
3.3 HTML措置实例二
下面我们来看看另外一个措置HTML的例子。这一次,我们假定Web办事器从widgets.acme.com移到了newserver.acme.com。现在你要点窜一些页面中的链接:
履行这个搜刮的正则表达式如图十三所示:

图十三:婚配点窜前的链接

如果可以或许婚配这个正则表达式,你可以用下面的内容替代图十三的链接:
重视#字符的前面加上了$1。Perl正则表达式语法用$1、$2等表示已婚配且提取出来的组。图十三的表达式把所有作为一个组婚配和提取出来的内容附加到链接的前面。
现在,前往Java。就象前面我们所做的那样,你必须建立测试字符串,建立把正则表达式编译到Pattern工具所必须的工具,和建立一个PatternMatcher工具:
接上去,用com.oroinc.text.regex包Util类的substitute()静态体例进行替代,输入成果字符串:
Util.substitute()体例的语法以下:
这个调用的前两个参数是之前建立的PatternMatcher和Pattern工具。第三个参数是一个Substiution工具,它决定了替代操纵若何进行。本例利用的是Perl5Substitution工具,它可以或许进行Perl5气势的替代。第四个参数是想要进行替代操纵的字符串,最后一个参数许可指定是不是替代形式的所有婚配子串(Util.SUBSTITUTE_ALL),或只替代指定的次数。
【结束语】在这篇文章中,我为你介绍了正则表达式的强年夜服从。只需精确应用,正则表达式可以或许在字符串提取和文本点窜中起到很年夜的感化。别的,我还介绍了如安在Java法度中经由过程Jakarta-ORO库操纵正则表达式。至于终究采取老式的字符串措置体例(利用StringTokenizer,charAt,和substring),还是采取正则表达式,这就有待你本身决定了。
------分开线----------------------------
标签(Tag):Java JAVA实例教程 JAVA根本教程 Java源代码 Java技能
------分开线----------------------------
保举内容
猜你感兴趣