正則表達式是定義字串搜尋模式的字元序列。若你曾使用 Perl、PHP、Python、JavaScript 等內建支援正則的語言,便知其處理文字之便利。Java 自 JDK 1.4 起透過 java.util.regex 原生支援;更早版本可使用 Apache Jakarta-ORO 函式庫。
.比對任意單一字元(含空白、Tab、換行)。例:t.n 可比對 tan、ten、tin、ton、t#n、t n 等。
[] 指定字元集合僅比對括號內字元。例:t[aeio]n 僅比對 tan、ten、tin、ton;Toon 不符合(因方括號僅比對單一字元)。
| 與分組 ()需比對多字元選項時使用 | 搭配圓括號分組。例:t(a|e|i|o|oo)n 可比對 tan、ten、tin、ton、toon。
| 符號 | 說明 |
|---|---|
* | 零次或多次 {0,} |
+ | 一次或多次 {1,} |
? | 零次或一次 {0,1} |
{n} | 恰好 n 次 |
{n,m} | n 到 m 次 |
{n,} | 至少 n 次 |
999-99-9999:\d{3}-\d{2}-\d{4}\d{3}-?\d{2}-?\d{4}[0-9]{4}[A-Z]{2}
^在方括號內表示排除。例:[^X]\w* 比對非 X 開頭的單字。
例:(\w+)\s+(\d{1,2}),\s+(\d{4}) 可從 June 26, 1951 擷取月份、日期、年份。使用 \s 比對空白字元。
| 符號 | 等價寫法 | 說明 |
|---|---|---|
\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] | 非空白字元 |
Jakarta-ORO(前身 OROMatcher)是功能最完整、效能最佳的開源正則函式庫之一,完整相容 Perl 5 語法。主要類別:
Perl5Compiler)。Perl5Matcher),提供 matches()、matchesPrefix()、contains() 等方法。PatternCompiler compiler = new Perl5Compiler();
Pattern pattern = compiler.compile("t[aeio]n"); // 大小寫敏感
// 或
Pattern pattern = compiler.compile("t[aeio]n", Perl5Compiler.CASE_INSENSITIVE_MASK);
PatternMatcher matcher = new Perl5Matcher();
boolean found = matcher.contains(inputString, pattern); // 子字串比對
BEA WebLogic 日誌格式範例:10.0.0.1 - - [26/Jun/2005:10:30:45 -0700] "GET /index.html HTTP/1.1" 200 1234
正則表達式(含分組擷取):
(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s-\s-\s(\[.*?\])
(\d{1,3}\.){3}\d{1,3} 比對 IP 位址(句點需跳脫)。\[.*?\] 比對方括號內的時間戳記(非貪婪模式)。\s-\s-\s 比對固定分隔符。String logEntry = "10.0.0.1 - - [26/Jun/2005:10:30:45 -0700] ...";
String regex = "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\s-\\s-\\s(\\[.*?\\])";
// Java 字串中 \ 需雙重跳脫
PatternCompiler compiler = new Perl5Compiler();
Pattern pattern = compiler.compile(regex);
PatternMatcher matcher = new Perl5Matcher();
if (matcher.contains(logEntry, pattern)) {
MatchResult result = matcher.getMatch();
System.out.println("IP: " + result.group(1));
System.out.println("Time: " + result.group(2));
}
目標:從 <FONT face="Arial, Serif" size="+2" color="red"> 擷取所有屬性並拆解為名稱-值對。
採用兩階段正則:
<FONT\s+([^>]*)>(\w+)\s*=\s*"([^"]*)"將 widgets.acme.com 替換為 newserver.acme.com,保留路徑。
String regex = "(https://)widgets\\.acme\\.com(/.*)";
String replacement = "$1newserver.acme.com$2";
// $1、$2 為 Perl 風格反向參考,對應第一、二組
使用 Util.substitute() 執行替換:
String result = Util.substitute(matcher, pattern,
new Perl5Substitution(replacement),
inputString,
Util.SUBSTITUTE_ALL);
正則表達式是文字處理的利器,善用可大幅簡化字串擷取、驗證、替換、分割等工作。Jakarta-ORO 提供完整 Perl 5 相容 API,是 Java 專案引入正則功能的優秀選擇(JDK 1.4+ 專案建議直接使用原生 java.util.regex)。選擇傳統字串處理(StringTokenizer、charAt、substring)或正則表達式,端視專案複雜度與團隊熟悉度而定。