作者杨中科是CowNew开源团队JDBMonitor项目组的开发人员。
CowNew开源团队网站
http://www.cownew.com论坛
http://www.cownew.com/newpeng/转载请注明此版权信息
正则表达式是一个非常强大的工具,有了这个工具,在进行字符串的解析、修改等不会再麻烦,比写一堆if else语句更清晰易懂。
关于正则表达式的基础知识我这里不再多讲,大家可以到网上查找相关的资料。本文假定您已经熟悉正则表达式的基本使用。
让我们以最好用的数据库监控、日志工具JDBMonitor为例来讲解。JDBMonitor的二进制jar包和源代码都可以从 http://www.cownew.com 下载得到。
DataBaseDBListener要读取形如"dburl=jdbc:odbc:MQIS;user=sa;password=sa;logtable=T_Log_Log"的配置字符串,然后从中解析数据库连接配置、表名等信息,并且user=sa;password和logtable部分也是可以忽略的(这是当然的,因为有的数据库不需要用户名密码,而且logtable也有默认值)。
打开com.cownew.JDBMonitor.listenerImpl.DataBaseDBListener,init就是进行参数arg的解析的:
1、Pattern patAll = Pattern.compile("dburl=(.+?);?(user=.*;password=.*;)?(logtable=.+)?");
这句是从arg中提取三个部分,分别是dburl部分,用户名密码部分,logtable部分。因为用户名密码部分,logtable部分是可以忽略的,因此采用"?"来标识这个两个分组“(user=.*;password=.*;)?”、“(logtable=.+)?”。而一旦dburl部分,用户名密码部分忽略,那么dburl=...后的;也是可以忽略的,因此";?"。
值得我们注意的是“dburl=(.+?)”,为什么不是"dburl=(.+)"呢?怎么多了个?。你可以尝试去掉“?”后,再次运行。你会看到dburl=后所有的字符,包括用户名密码部分,logtable部分都被看成dburl=的值了,也就是后边的字符都被吃掉了。为什么呢?
这就要提到正则表达式的贪婪性和懒惰性,关于贪婪性和懒惰性可以查看网上一篇文章《深入浅出之正则表达式》(http://dragon.cnblogs.com/archive/2006/05/08/394078.html)。
象《深入浅出之正则表达式》描述的那样:“+”是贪婪的。也就是说,“+”会导致正则表达式引擎试图尽可能的重复前导字符。只有当这种重复会引起整个正则表达式匹配失败的情况下,引擎会进行回溯。也就是说,它会放弃最后一次的“重复”,然后处理正则表达式余下的部分。一个用于修正以上问题的可能方案是用“+”的惰性代替贪婪性。你可以在“+”后面紧跟一个问号“?”来达到这一点。“*”,“{}”和“?”表示的重复也可以用这个方案。
因此JDBMonitor就采用了dburl=(.+?)来解决这个贪婪性问题。
2、Pattern patUserPwd = Pattern.compile("user=(.*);password=(.*);");
在第一步中把“user=sa;password=sa;”当成一个整体来提取,那么我们接下来还要从这个提取中的串中提取用户名user、密码password信息。因此采用这种方式来提取。这种分步提取的方式比写复杂的正则表达式一次性提取看起来更清晰,更加易维护。