三、应用实例
下面我们来看看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编译正则表达式创建

现在,创建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对象之中的每一次迭代将把它内部的指针向前移动,下一次检测将从前一次匹配位置的后面开始。
本例的输出结果如下:
闽公网安备 35060202000074号