作者楊中科是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信息。因此采用這種方式來提取。這種分步提取的方式比寫復雜的正則表達式一次性提取看起來更清晰,更加易維護。