服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

java中正则表达式的应用(1)

正则表达式是一种可以用于模式匹配和替换的强有力的工具,一个正则表达式就是由普通的字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式,它描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

正则表达式在字符数据处理中起着非常重要的作用,我们可以用正则表达式完成大部分的数据分析处理工作,如:判断一个串是否是数字、是否是有效的email地址,从海量的文字资料中提取有价值的数据等等,如果不使用正则表达式,那么实现的程序可能会很长,并且容易出错。对这点本人深有体会,面对大量工具书电子档资料的整理工作,如果不懂得应用正则表达式来处理,那么将是很痛苦的一件事情,反之则将可以轻松地完成,获得事半功倍的效果。

由于本文目的是要介绍如何在java里运用正则表达式,因此对刚接触正则表达式的读者请参考有关资料,在此因篇幅有限不作介绍。

java对正则表达式的支持:

在jdk1.3 或之前的jdk版本中并没有包含正则表达式库可供java程序员使用,之前我们一般都在使用第三方提供的正则表达式库,这些第三方库中有源代码开放的,也有需付费购买的,而现时在jdk1.4的测试版中也已经包含有正则表达式库---java.util.regex。

故此现在我们有很多面向java的正则表达式库可供选择,以下我将介绍两个较具代表性的 jakarta-oro和 java.util.regex,首先当然是本人一直在用的 jakarta-oro:

jakarta-oro正则表达式库

1.简介:

jakarta-oro是最全面以及优化得最好的正则表达式api之一,jakarta-oro库以前叫做oromatcher,是由daniel f. savarese编写,后来他将其赠与jakarta project,读者可在apache.org的网站 下载该api包。

许多源代码开放的正则表达式库都是支持perl5兼容的正则表达式语法,jakarta-oro正则表达式库也不例外,他与perl 5正则表达式完全兼容。

2.对象与其方法:

★patterncompiler对象:

我们在使用jakarta-oro api包时,最先要做的是,创建一个perl5compiler类的实例,并把它赋值给patterncompiler接口对象。 perl5compiler是patterncompiler接口的一个实现,允许你把正则表达式编译成用来匹配的pattern对象。

patterncompiler compiler=new perl5compiler();

★pattern对象:

要把所对应的正则表达式编译成pattern对象,需要调用compiler对象的compile()方法,并在调用参数中指定正则表达式。举个例子,你可以按照下面这种方式编译正则表达式"s[ahkl]y":

pattern pattern=null;

try {

pattern=compiler.compile("s[ahkl]y ");

} catch (malformedpatternexception e) {

e.printstacktrace();

}

在默认的情况下,编译器会创建一个对大小写敏感的模式(pattern)。因此,上面代码编译得到的模式只匹配"say"、"shy"、 "sky"和"sly",但不匹配"say"和"sky"。要创建一个大小写不敏感的模式,你应该在调用编译器的时候指定一个额外的参数:

pattern=compiler.compile("s[ahkl]y",perl5compiler.case_insensitive_mask);

pattern对象创建好之后,就可以通过patternmatcher类用该pattern对象进行模式匹配。

★patternmatcher对象:

patternmatcher 对象依据pattern对象和字符串展开匹配检查。你要实例化一个perl5matcher类并把结果赋值给patternmatcher接口。 perl5matcher类是patternmatcher接口的一个实现,它根据perl 5正则表达式语法进行模式匹配:

patternmatcher matcher=new perl5matcher();

patternmatcher对象提供了多个方法进行匹配操作,这些方法的第一个参数都是需要根据正则表达式进行匹配的字符串:

1. boolean matches(string input, pattern pattern):当要求输入的字符串input和正则表达式pattern精确匹配时使用该方法。也就是说当正则表达式完整地描述输入字符串时返回真值。

2. boolean matchesprefix(string input, pattern pattern):要求正则表达式匹配输入字符串起始部分时使用该方法。也就是说当输入字符串的起始部分与正则表达式匹配时返回真值。

3. boolean contains(string input, pattern pattern):当正则表达式要匹配输入字符串的一部分时使用该方法。当正则表达式为输入字符串的子串时返回真值。

但以上三种方法只会查找输入字符串中匹配正则表达式的第一个对象,如果当字符串可能有多个子串匹配给定的正则表达式时,那么你就可以在调用上面三个方法时用 patternmatcherinput对象作为参数替代string对象,这样就可以从字符串中最后一次匹配的位置开始继续进行匹配,这样就方便的多了。

用patternmatcherinput对象作为参数替代string时,上述三个方法的语法如下:

1. boolean matches(patternmatcherinput input, pattern pattern)

2. boolean matchesprefix(patternmatcherinput input, pattern pattern)

3. boolean contains(patternmatcherinput input, pattern pattern)

★util.substitute()方法:

查找后需要要进行替换,我们就要用到util.substitute()方法,其语法如下:

public static string substitute(patternmatcher matcher,

pattern pattern,substitution sub,string input,

int numsubs)

前两个参数分别为patternmatcher和pattern 对象。而第三个参数是个substiution对象,由它来决定替换操作如何进行。第四个参数是要进行替换操作的目标字符串,最后一个参数用来指定是否替换模式的所有匹配子串(util.substitute_all),或只进行指定次数的替换。

在这里我相信有必要详细解说一下第三个参数substiution对象,因为它将决定替换将怎样进行。

substiution:

substiution 是一个接口类,它为你提供了在使用util.substitute()方法时控制替换方式的手段,它有两个标准的实现类: stringsubstitution与perl5substitution。当然,同时你也可以生成自己的实现类来定制你所需要的特殊替换动作。

stringsubstitution:

stringsubstitution 实现的是简单的纯文字替换手段,它有两个构造方法:

stringsubstitution()->缺省的构造方法,初始化一个包含零长度字符串的替换对象。

stringsubstitution(java.lang.string substitution)->初始化一个给定字符串的替换对象。

perl5substitution:

perl5substitution 是stringsubstitution的子类,它在实现纯文字替换手段的同时也允许进行针对math类里各匹配组的perl5变量的替换,所以他的替换手段比其直接父类stringsubstitution更为多元化。

它有三个构造器:

perl5substitution()

perl5substitution(java.lang.string substitution)

perl5substitution(java.lang.string substitution, int numinterpolations)

前两种构造方法与stringsubstitution一样,而第三种构造方法下面将会介绍到。

在 perl5substitution的替换字符串中可以包含用来替代在正则表达式里由小扩号围起来的匹配组的变量,这些变量是由$1, $2,$3等形式来标识。我们可以用一个例子来解释怎样使用替换变量来进行替换:

假设我们有正则表达式模式为b/d+:(也就是b[0-9]+:),而我们想把所有匹配的字符串中的"b"都改为"a",而":"则改为"-",而其余部分则不作修改,如我们输入字符串为"example b123:",经过替换后就应该变成"example a123-"。要做到这点,我们就首先要把不做替换的部分用分组符号小括号包起来,这样正则表达式就变为"b(/d+):",而构造 perl5substitution对象时其替换字符串就应该是"a$1-",也就是构造式为perl5substitution("a$1-"),表示在使用util.substitute()方法时只要在目标字符串里找到和正则表达式" b(/d+): "相匹配的子串都用替换字符串来替换,而变量$1表示如果和正则表达式里第一个组相匹配的内容则照般原文插到$1所在的为置,如在"example b123:"中和正则表达式相匹配的部分是"b123:",而其中和第一分组"(/d+)"相匹配的部分则是"123",所以最后替换结果为 "example a123-"。

有一点需要清楚的是,如果你把构造器perl5substitution(java.lang.string substitution,int numinterpolations)

中的numinterpolations参数设为interpolate_all,那么当每次找到一个匹配字串时,替换变量($1,$2等)所指向的内容都根据目前匹配字串来更新,但是如果numinterpolations参数设为一个正整数n时,那么在替换时就只会在前n次匹配发生时替换变量会跟随匹配对象来调整所代表的内容,但n次之后就以一致以第n次替换变量所代表内容来做为以后替换结果。

举个例子会更好理解:

假如沿用以上例子中的正则表达式模式以及替换内容来进行替换工作,设目标字符串为"tank b123: 85 tank b256: 32 tank b78: 22",并且设numinterpolations参数为interpolate_all,而util.substitute()方法中的numsub变量设为substitute_all(请参考上文util.substitute()方法内容),那么你获得的替换结果将会是: tank a123- 85 tank a256- 32 tank a78- 22

但是如果你把numinterpolations设为2,并且numsubs依然设为substitute_all,那么这时你获得的结果则会是: tank a123- 85 tank a256- 32 tank a256- 22

你要注意到最后一个替换所用变量$1所代表的内容与第二个$1一样为"256",而不是预期的"78",因为在替换进行中,替换变量$1只根据匹配内容进行了两次更新,最后一次就使第二次匹配时所更新的结果,那么我们可以由此知道,如果numinterpo

扫描关注微信公众号