若你曾使用過 Perl 或其他內建正則表達式支援的語言,定能體會正則表達式在文本處理與模式匹配上的強大與便捷。對於初接觸者,「正則表達式」是一組定義搜尋模式的字元串。許多語言(Perl、PHP、Python、JavaScript、JScript)皆支援正則表達式處理文本,文本編輯器亦常用其實現高階「搜尋-替換」功能。Java 方面,本文撰寫時,一項包含正則表達式文本處理的 Java 規範請求(JSR)已獲認可,預期將在後續 JDK 版本中原生支援。但在此之前,開發者可從 Apache.org 下載開源的 Jakarta-ORO 函式庫。本文將先介紹正則表達式基礎,再以 Jakarta-ORO API 為例示範實戰應用。
句點符號是通配符,匹配任意單一字元(含空格、Tab、換行)。例如欲尋找以「t」開頭、「n」結尾的三字母單詞,正則表達式為 t.n,可匹配 tan、ten、tin、ton,亦會匹配 t#n、tpn、t n 等無意義組合。
為限制匹配範圍,可在方括號內指定允許的字元。t[aeio]n 僅匹配 tan、ten、tin、ton;Toon 不匹配,因方括號僅匹配單一字元。
若需同時匹配 toon,可用 t(a|e|i|o|oo)n。| 代表「或」運算,此處必須使用圓括號 () 分組,因方括號僅限單字元。
常用量詞:
*:零次或多次+:一次或多次?:零次或一次{n}:恰好 n 次{n,}:至少 n 次{n,m}:n 到 m 次例如美國社會安全號碼格式 999-99-9999,正則為 \d{3}-\d{2}-\d{4}。連字符 - 在正則中有特殊含義(表示範圍),故需轉義為 \-。若連字符可有可無,可用 \d{3}-?\d{2}-?\d{4}。
美國車牌格式(四數字 + 兩字母):[0-9]{4}[A-Z]{2}。
在方括號內,^ 表示排除。[^X] 匹配非「X」開頭的單詞。
圓括號用於分組擷取。若要從 June 26, 1951 格式日期中提取月份,正則為 (\w+)\s+\d{1,2},\s+\d{4},其中 \s 匹配所有空白字元。第一組 (\w+) 即為月份。
| 符號 | 含義 | 等價 |
|---|---|---|
| \d | 數字 | [0-9] |
| \D | 非數字 | [^0-9] |
| \w | 單字字元(字母、數字、底線) | [a-zA-Z0-9_] |
| \W | 非單字字元 | [^a-zA-Z0-9_] |
| \s | 空白字元 | [ \t\n\r\f] |
| \S | 非空白字元 | [^ \t\n\r\f] |
社會安全號碼正則可簡化為 \d{3}-\d{2}-\d{4}。
Jakarta-ORO(原 OROMatcher)是最全面、最優化且完全相容 Perl 5 語法的 Java 正則 API 之一。核心類別包括:
建立 Perl5Compiler 實例並指派給 PatternCompiler 介面,用於將正則字串編譯為 Pattern 物件。
呼叫 compiler.compile("t[aeio]n") 編譯正則。預設大小寫敏感;若需忽略大小寫,傳入 Perl5Compiler.CASE_INSENSITIVE_MASK 旗標。
建立 Perl5Matcher 實例進行匹配,提供三種主要方法:
matches(input, pattern):輸入字串需與正則完全匹配matchesPrefix(input, pattern):正則匹配輸入字串開頭contains(input, pattern):正則匹配輸入字串任一子串若字串含多處匹配,可使用 PatternMatcherInput 物件替代 String,從上次匹配位置繼續搜尋。
任務:分析 WebLogic 日誌,統計各用戶停留時間。日誌格式含 IP 與時間戳記。IP 正則:(\d{1,3}\.){3}\d{1,3}(注意句點需轉義)。時間戳記被 [] 包圍,正則:\[([^\]]+)\]。合併並加入分組:((\d{1,3}\.){3}\d{1,3})\s-\s-\s(\[([^\]]+)\])。Java 中反斜線需雙重轉義(\\)。
兩階段正則:第一階段擷取完整屬性字串 ]+)>;第二階段將屬性拆解為名值對 (\w+)\s*=\s*"([^"]*)"。使用 PatternMatcherInput 迭代提取所有屬性。
需將 widgets.acme.com 連結改為 newserver.acme.com。搜尋正則:(href\s*=\s*")https://widgets\.acme\.com(/[^"]*")。替換字串:$1https://newserver.acme.com$2,其中 $1、$2 為分組回參。使用 Util.substitute() 執行替換,支援 SUBSTITUTE_ALL 全域替換。