作者楊中科是CowNew開源團(tuán)隊(duì)JDBMonitor項(xiàng)目組的開發(fā)人員。
CowNew開源團(tuán)隊(duì)網(wǎng)站
http://www.cownew.com論壇
http://www.cownew.com/newpeng/轉(zhuǎn)載請(qǐng)注明此版權(quán)信息
正則表達(dá)式是一個(gè)非常強(qiáng)大的工具,有了這個(gè)工具,在進(jìn)行字符串的解析、修改等不會(huì)再麻煩,比寫一堆if else語(yǔ)句更清晰易懂。
關(guān)于正則表達(dá)式的基礎(chǔ)知識(shí)我這里不再多講,大家可以到網(wǎng)上查找相關(guān)的資料。本文假定您已經(jīng)熟悉正則表達(dá)式的基本使用。
讓我們以最好用的數(shù)據(jù)庫(kù)監(jiān)控、日志工具JDBMonitor為例來(lái)講解。JDBMonitor的二進(jìn)制jar包和源代碼都可以從 http://www.cownew.com 下載得到。
DataBaseDBListener要讀取形如"dburl=jdbc:odbc:MQIS;user=sa;password=sa;logtable=T_Log_Log"的配置字符串,然后從中解析數(shù)據(jù)庫(kù)連接配置、表名等信息,并且user=sa;password和logtable部分也是可以忽略的(這是當(dāng)然的,因?yàn)橛械臄?shù)據(jù)庫(kù)不需要用戶名密碼,而且logtable也有默認(rèn)值)。
打開com.cownew.JDBMonitor.listenerImpl.DataBaseDBListener,init就是進(jìn)行參數(shù)arg的解析的:
1、Pattern patAll = Pattern.compile("dburl=(.+?);?(user=.*;password=.*;)?(logtable=.+)?");
這句是從arg中提取三個(gè)部分,分別是dburl部分,用戶名密碼部分,logtable部分。因?yàn)橛脩裘艽a部分,logtable部分是可以忽略的,因此采用"?"來(lái)標(biāo)識(shí)這個(gè)兩個(gè)分組“(user=.*;password=.*;)?”、“(logtable=.+)?”。而一旦dburl部分,用戶名密碼部分忽略,那么dburl=...后的;也是可以忽略的,因此";?"。
值得我們注意的是“dburl=(.+?)”,為什么不是"dburl=(.+)"呢?怎么多了個(gè)?。你可以嘗試去掉“?”后,再次運(yùn)行。你會(huì)看到dburl=后所有的字符,包括用戶名密碼部分,logtable部分都被看成dburl=的值了,也就是后邊的字符都被吃掉了。為什么呢?
這就要提到正則表達(dá)式的貪婪性和懶惰性,關(guān)于貪婪性和懶惰性可以查看網(wǎng)上一篇文章《深入淺出之正則表達(dá)式》(http://dragon.cnblogs.com/archive/2006/05/08/394078.html)。
象《深入淺出之正則表達(dá)式》描述的那樣:“+”是貪婪的。也就是說(shuō),“+”會(huì)導(dǎo)致正則表達(dá)式引擎試圖盡可能的重復(fù)前導(dǎo)字符。只有當(dāng)這種重復(fù)會(huì)引起整個(gè)正則表達(dá)式匹配失敗的情況下,引擎會(huì)進(jìn)行回溯。也就是說(shuō),它會(huì)放棄最后一次的“重復(fù)”,然后處理正則表達(dá)式余下的部分。一個(gè)用于修正以上問題的可能方案是用“+”的惰性代替貪婪性。你可以在“+”后面緊跟一個(gè)問號(hào)“?”來(lái)達(dá)到這一點(diǎn)?!?”,“{}”和“?”表示的重復(fù)也可以用這個(gè)方案。
因此JDBMonitor就采用了dburl=(.+?)來(lái)解決這個(gè)貪婪性問題。
2、Pattern patUserPwd = Pattern.compile("user=(.*);password=(.*);");
在第一步中把“user=sa;password=sa;”當(dāng)成一個(gè)整體來(lái)提取,那么我們接下來(lái)還要從這個(gè)提取中的串中提取用戶名user、密碼password信息。因此采用這種方式來(lái)提取。這種分步提取的方式比寫復(fù)雜的正則表達(dá)式一次性提取看起來(lái)更清晰,更加易維護(hù)。