Java 正則表達式的使用實戰(zhàn)案例
下面是 Java 正則表達式詳細的使用指南,涵蓋語法細節(jié)、核心類方法、高級特性及實戰(zhàn)案例:
一、正則表達式語法詳解
1. 基礎(chǔ)字符匹配
- 普通字符:直接匹配自身(如
a匹配 "a",3匹配 "3")。 - 轉(zhuǎn)義字符:用
\\表示特殊含義(Java 中需雙重轉(zhuǎn)義):\\.匹配.(避免被解讀為任意字符)\\*匹配*(避免被解讀為量詞)\\n匹配換行符,\\t匹配制表符
2. 字符類([]定義)
- 枚舉匹配:
[abc]匹配a/b/c;[0-9]匹配任意數(shù)字(等價于\\d)。 - 排除匹配:
[^abc]匹配非a/b/c的字符。 - 范圍組合:
[a-zA-Z0-9]匹配字母或數(shù)字(等價于\\w)。 - 預(yù)定義字符類:
\\d=[0-9](數(shù)字)\\D=[^0-9](非數(shù)字)\\s=[ \t\n\x0B\f\r](空白符)\\S=[^ \t\n\x0B\f\r](非空白符)\\w=[a-zA-Z_0-9](單詞字符)\\W=[^a-zA-Z_0-9](非單詞字符)
3. 量詞(控制匹配次數(shù))
- 貪婪模式(默認):盡可能多匹配:
*:0 次或多次(a*匹配""、"a"、"aa"...)+:1 次或多次(a+匹配"a"、"aa"...)?:0 次或 1 次(a?匹配""或"a"){n}:恰好 n 次(a{3}匹配"aaa"){n,}:至少 n 次(a{2,}匹配"aa"、"aaa"...){n,m}:n 到 m 次(a{1,3}匹配"a"、"aa"、"aaa")
- 非貪婪模式:在量詞后加
?,盡可能少匹配:a*?:匹配 0 次或多次,但優(yōu)先最短(如"aaaa"中匹配"")a+?:匹配 1 次即可(如"aaaa"中匹配"a")
4. 邊界匹配
^:行的開頭(^abc匹配以"abc"開頭的字符串)。$:行的結(jié)尾(abc$匹配以"abc"結(jié)尾的字符串)。\\b:單詞邊界(\\bcat\\b匹配獨立單詞"cat",不匹配"category"中的"cat")。\\B:非單詞邊界(\\Bcat\\B匹配"category"中的"cat")。
5. 分組與引用
- 捕獲分組:用
()定義,可通過group(n)提?。?Pattern p = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})"); // 年-月-日分組 Matcher m = p.matcher("2023-10-05"); if (m.matches()) { String year = m.group(1); // "2023" String month = m.group(2); // "10" } - 非捕獲分組:用
(?:pattern)定義,僅用于分組不捕獲(節(jié)省性能):Pattern p = Pattern.compile("(?:https?):\\/\\/"); // 匹配http://或https://,不捕獲 - 反向引用:用
\\n引用第 n 個分組的內(nèi)容(替換時用$n):// 交換兩個數(shù)字(如"12-34" → "34-12") String result = "12-34".replaceAll("(\\d+)-(\\d+)", "$2-$1");
6. 零寬斷言(預(yù)查)
- 正向肯定預(yù)查:
(?=pattern)匹配后面緊跟pattern的位置:Pattern p = Pattern.compile("\\d+(?=元)"); // 匹配后面是"元"的數(shù)字(如"100元"中的"100") - 正向否定預(yù)查:
(?!pattern)匹配后面不緊跟pattern的位置:Pattern p = Pattern.compile("\\d+(?!元)"); // 匹配后面不是"元"的數(shù)字(如"100個"中的"100") - 反向肯定預(yù)查:
(?<=pattern)匹配前面是pattern的位置:Pattern p = Pattern.compile("(?<=¥)\\d+"); // 匹配前面是"¥"的數(shù)字(如"¥100"中的"100") - 反向否定預(yù)查:
(?<!pattern)匹配前面不是pattern的位置:Pattern p = Pattern.compile("(?<!¥)\\d+"); // 匹配前面不是"¥"的數(shù)字(如"$100"中的"100")
二、Pattern 類詳解
1. 編譯方法與標志
// 基本編譯 Pattern pattern = Pattern.compile(regex); // 帶標志編譯(多標志用 | 分隔) Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
常用標志:
CASE_INSENSITIVE:忽略大小寫(如a匹配A)。MULTILINE:多行模式(^匹配每行開頭,$匹配每行結(jié)尾)。DOTALL:s模式,.匹配包括換行符\n在內(nèi)的所有字符。UNICODE_CASE:結(jié)合CASE_INSENSITIVE,支持 Unicode 字符大小寫匹配。COMMENTS:忽略正則中的空格和#注釋(需用(?x)開啟內(nèi)聯(lián)注釋)。
2. 常用方法
matcher(CharSequence input):創(chuàng)建 Matcher 對象。split(CharSequence input):按匹配規(guī)則分割字符串(返回數(shù)組):String[] parts = Pattern.compile("\\|").split("a|b|c"); // ["a", "b", "c"]matches(String regex, CharSequence input):靜態(tài)方法,直接判斷全匹配。
三、Matcher 類詳解
1. 匹配狀態(tài)方法
matches():全字符串匹配(整個字符串必須符合正則)。lookingAt():從字符串開頭匹配(不必匹配全部):Matcher m = Pattern.compile("\\d+").matcher("123abc"); m.lookingAt(); // true(匹配"123")find():查找下一個匹配子串(可循環(huán)調(diào)用):Matcher m = Pattern.compile("\\d+").matcher("a123b456"); while (m.find()) { System.out.println(m.group()); // 依次輸出"123"、"456" }start()/end():返回當前匹配的起始 / 結(jié)束索引(end()是匹配后一位):m.find(); // 匹配"123" m.start(); // 1("123"在字符串中的起始索引) m.end(); // 4("123"結(jié)束索引的下一位)
2. 替換與修改方法
replaceAll(String replacement):替換所有匹配。replaceFirst(String replacement):替換第一個匹配。appendReplacement(StringBuffer sb, String replacement):逐步替換并追加到緩沖區(qū)(靈活控制替換過程):StringBuffer sb = new StringBuffer(); Matcher m = Pattern.compile("\\d+").matcher("a123b456"); while (m.find()) { m.appendReplacement(sb, "*" + m.group() + "*"); // 包裹數(shù)字 } m.appendTail(sb); // 追加剩余部分 System.out.println(sb.toString()); // "a*123*b*456*"
3. 重置與重新配置
reset():重置匹配器狀態(tài),可重新輸入字符串:matcher.reset("new string"); // 重新匹配新字符串usePattern(Pattern newPattern):更換正則模式(復(fù)用 Matcher 對象)。
四、實戰(zhàn)案例
1. 驗證手機號(中國大陸)
String regex = "^1[3-9]\\d{9}$"; // 1開頭,第二位3-9,共11位
boolean isValid = Pattern.matches(regex, "13800138000"); // true
2. 提取 URL 中的域名
String url = "https://www.example.com/path?query=1";
Pattern p = Pattern.compile("(?<=https?://)(\\w+\\.)+\\w+");
Matcher m = p.matcher(url);
if (m.find()) {
String domain = m.group(); // "www.example.com"
}
3. 清除 HTML 標簽
String html = "<div><p>Hello</p></div>";
String text = html.replaceAll("<[^>]+>", ""); // 替換所有標簽為空白 → "Hello"
4. 格式化數(shù)字(每 3 位加逗號)
String number = "123456789";
String formatted = number.replaceAll("(\\d)(?=(\\d{3})+$)", "$1,"); // "123,456,789"
五、性能與避坑指南
- 避免災(zāi)難性回溯:復(fù)雜正則(如
(a+)+b匹配aaaaa)可能導(dǎo)致性能爆炸,建議簡化或拆分。 - 預(yù)編譯復(fù)用:頻繁使用的正則用
Pattern預(yù)編譯,避免重復(fù)編譯開銷。 - 轉(zhuǎn)義陷阱:注意特殊字符轉(zhuǎn)義(如
.、*、(需加\\)。 - 貪婪與非貪婪選擇:根據(jù)需求選擇模式(如提取標簽用
.*?而非.*)。 - 分組索引:
group(0)是全匹配,分組從1開始計數(shù)。
通過掌握上述細節(jié),可應(yīng)對 Java 中絕大多數(shù)正則表達式場景,包括字符串驗證、提取、格式化等復(fù)雜需求。正則表達式的核心在于多練習(xí),結(jié)合具體場景調(diào)試模式。
到此這篇關(guān)于Java 正則表達式的使用實戰(zhàn)案例的文章就介紹到這了,更多相關(guān)java正則表達式使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot 集成 Kafkad的實現(xiàn)示例
這篇文章主要介紹了Spring Boot 集成 Kafkad的示例,幫助大家更好的理解和學(xué)習(xí)使用Spring Boot框架,感興趣的朋友可以了解下2021-04-04
Java中使用MongoDB數(shù)據(jù)庫實例Demo
MongoDB是由C++語言編寫的,基于分布式文件存儲的數(shù)據(jù)庫,是一個介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的產(chǎn)品,是最接近于關(guān)系型數(shù)據(jù)庫的NoSQL數(shù)據(jù)庫,下面這篇文章主要給大家介紹了關(guān)于Java中使用MongoDB數(shù)據(jù)庫的相關(guān)資料,需要的朋友可以參考下2023-12-12
解決Springboot整合shiro時靜態(tài)資源被攔截的問題
這篇文章主要介紹了解決Springboot整合shiro時靜態(tài)資源被攔截的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
IntelliJIDEA中實現(xiàn)SpringBoot多實例運行的兩種方式
在微服務(wù)開發(fā)中,經(jīng)常需要同時啟動多個服務(wù)實例進行測試或模擬集群環(huán)境,?IntelliJ?IDEA?作為Java開發(fā)者常用工具,提供了靈活的多實例啟動支持,本文將詳細介紹如何通過修改配置?和批量啟動?兩種方式實現(xiàn)SpringBoot多實例運行,并解決常見問題,需要的朋友可以參考下2025-03-03
詳解Springboot整合Dubbo之代碼集成和發(fā)布
本篇文章主要介紹了Springboot整合Dubbo之代碼集成和發(fā)布,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12

