一、什么是正則表達式?
正則表達式(Regular Expression)是一種文本模式,用于描述、匹配、搜索或替換符合某種規則的字符串。其在日志提取、表單校驗、配置清洗、數據爬取等場景中被廣泛使用。
Java 提供了完整的正則表達式支持,核心類如下:
java.util.regex.Pattern
:編譯正則表達式java.util.regex.Matcher
:對文本進行匹配、提取String.matches()
/replaceAll()
/split()
等方法:簡化使用
示例代碼:
Pattern pattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
Matcher matcher = pattern.matcher("2025-07-10");
if (matcher.matches()) {System.out.println("匹配成功");
}
二、正則表達式語法概覽(核心語法)
語法 | 含義 | 示例 | 說明 |
---|---|---|---|
. | 任意字符(除換行) | a.c | 可匹配 abc , a9c 等 |
^ | 開始 | ^abc | 必須以 abc 開頭 |
$ | 結束 | xyz$ | 必須以 xyz 結尾 |
* | 0 次或多次 | a* | 可匹配 "" , a , aaaa |
+ | 1 次或多次 | a+ | 不匹配空串 |
? | 0 次或 1 次 | a? | 匹配 0 或 1 次 a |
{n} | 恰好 n 次 | a{3} | 匹配 aaa |
{n,} | 至少 n 次 | a{2,} | 至少兩個 a |
{n,m} | n~m 次 | a{2,4} | 2 到 4 個 a |
[] | 字符類 | [abc] | 匹配 a、b、c 中任意一個 |
[^] | 排除字符類 | [^abc] | 不匹配 a/b/c |
` | ` | 或 | `cat |
() | 分組 | (abc)+ | 分組重復匹配 |
\d | 數字 | \d+ | 等價于 [0-9]+ |
\w | 單詞字符 | [a-zA-Z0-9_] | |
\s | 空白字符 | 包括空格、換行、制表符 |
三、Java 使用建議(工程實踐)
1. 推薦寫法:Pattern + Matcher
Pattern pattern = Pattern.compile("^[a-zA-Z0-9_-]{4,16}$");
Matcher matcher = pattern.matcher("user_1234");
if (matcher.matches()) {// 合法用戶名
}
2. 避免錯誤寫法
// 錯誤:正則表達式字符串忘記轉義
Pattern.compile("\d{3}"); // 實際匹配的是"d{3}",不是數字
應寫為:
Pattern.compile("\\d{3}");
四、正則表達式學習路徑
第一階段:語法基礎
學習字符類(
[abc]
、\d
)、量詞(*
、+
、?
)、邊界(^
、$
)
第二階段:復雜匹配
分組與捕獲、非貪婪匹配、斷言(正向 / 負向)
第三階段:調試與性能
使用
Matcher
提取組信息、使用預編譯Pattern
避免重復編譯注意回溯型表達式造成的性能問題(避免
(a+)+
)
五、常見場景與對應正則表達式
1. 表單驗證(校驗用戶輸入)
場景 | 正則表達式 | 說明 |
---|---|---|
用戶名(4-16位) | ^[a-zA-Z0-9_-]{4,16}$ | 字母數字下劃線 |
中文名 | ^[\u4e00-\u9fa5]{2,10}$ | 只支持中文 |
郵箱 | ^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$ | 常見郵箱格式 |
手機號(中國) | ^1[3-9]\d{9}$ | 三大運營商 |
身份證(中國18位) | `^\d{6}(18 | 19 |
密碼強度(數字+字母) | ^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$ | 至少一個字母和數字 |
2. 網絡相關
場景 | 正則表達式 |
---|---|
IPv4 | `^((25[0-5] |
URL | `^(http |
域名 | ^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,}$ |
3. 時間與日期
場景 | 正則表達式 |
---|---|
日期(yyyy-MM-dd) | ^\d{4}-\d{2}-\d{2}$ |
時間(HH:mm:ss) | `^([01]\d |
年月日時間戳 | ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$ |
4. 日志抽取與數據清洗
場景 | 正則表達式 | 提示 |
---|---|---|
提取日志級別 | `\b(INFO | DEBUG |
提取 JSON 鍵值對 | "(\w+)":\s*"([^"]+)" | 適合簡單 JSON |
去除 HTML 標簽 | <[^>]+> | 清洗富文本 |
去除空白字符 | \s+ | 用于壓縮字符串 |
清除特殊字符 | [^a-zA-Z0-9\u4e00-\u9fa5] | 保留中英文與數字 |
六、常見問題與性能陷阱
?? 正則性能陷阱
(a+)+
會造成回溯爆炸,處理大文本時極其慢;避免重復編譯:將
Pattern
定義為靜態成員或緩存;替換時,盡量使用非捕獲組
(?:...)
避免組開銷;編寫復雜表達式時推薦加注釋(Java 8+ 支持
(?x)
模式):
Pattern.compile("(?x) # 啟用注釋模式\\d{4} # 年份- # 分隔符\\d{2} # 月份- # 日
");
七、構建正則表達式庫(正則標準化)
建議為團隊或項目構建統一正則工具類,方便調用與維護:
public class RegexLib {public static final String EMAIL = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$";public static final String PHONE = "^1[3-9]\\d{9}$";public static final String ID_CARD = "^\\d{17}[\\dXx]$";public static final String DATE = "^\\d{4}-\\d{2}-\\d{2}$";public static boolean match(String pattern, String input) {return Pattern.matches(pattern, input);}
}
使用:
if (RegexLib.match(RegexLib.EMAIL, "user@test.com")) {// 合法郵箱
}
八、總結:正則表達式在工程中的地位
在中大型項目中,正則表達式應作為工具語言中的基礎技能被系統掌握。學習正則不僅是掌握語法,更要理解其行為模型與性能特性,避免常見陷阱,構建可復用的正則庫。