Java正則表達式完全指南

Java正則表達式完全指南

    • 一、正則表達式基礎概念
      • 1.1 什么是正則表達式
      • 1.2 Java中的正則表達式支持
    • 二、正則表達式基本語法
      • 2.1 普通字符
      • 2.2 元字符
      • 2.3 預定義字符類
    • 三、Java中正則表達式的基本用法
      • 3.1 編譯正則表達式
      • 3.2 創建Matcher對象并執行匹配
      • 3.3 常用的Matcher方法
    • 四、正則表達式高級應用
      • 4.1 分組與捕獲
      • 4.2 反向引用
      • 4.3 貪婪匹配與非貪婪匹配
      • 4.4 零寬斷言
    • 五、正則表達式在實際開發中的應用
      • 5.1 表單驗證
        • 郵箱驗證
        • 手機號驗證
        • 身份證號碼驗證
      • 5.2 文本替換
        • 替換HTML標簽
        • 敏感詞過濾
      • 5.3 文本分割
        • 按逗號或空格分割
        • 按數字分割
    • 六、正則表達式性能優化
    • 七、常見問題與注意事項
    • 總結

正則表達式(Regular Expression,簡稱Regex)是一種強大的文本處理工具,它可以幫助開發者高效地進行字符串匹配、查找、替換和分割等操作。在Java中正則表達式的應用場景極為廣泛,從簡單的表單驗證到復雜的文本解析,都離不開正則表達式的支持。雖然之前我也講過正則表達式,但過于通用,今天本文將專門全面介紹Java中正則表達式的相關知識,從基礎語法到高級應用,并結合豐富實例代碼,帶你深入理解和掌握這一強大工具。

一、正則表達式基礎概念

1.1 什么是正則表達式

正則表達式是一種由字符和特殊符號組成的模式,用于描述字符串的特定格式規則。通過使用正則表達式,可以:

  • 檢查字符串是否符合特定格式(如郵箱、手機號)
  • 從文本中提取感興趣的內容(如URL、數字)
  • 替換文本中的特定部分
  • 將文本按特定規則分割

1.2 Java中的正則表達式支持

Java通過java.util.regex包提供對正則表達式的支持,主要涉及以下三個類:

  • Pattern:用于編譯正則表達式,將正則表達式字符串編譯為模式對象。
  • Matcher:用于執行匹配操作,對輸入字符串進行解釋和匹配操作。
  • PatternSyntaxException:用于處理正則表達式語法錯誤的異常類。

二、正則表達式基本語法

2.1 普通字符

普通字符包括沒有顯式指定為元字符的所有可打印和不可打印字符,它們直接匹配自身。例如:

  • abc 匹配字符串 “abc”
  • 123 匹配字符串 “123”

2.2 元字符

元字符是正則表達式中具有特殊含義的字符,常用的元字符及其含義如下:

元字符描述
.匹配除換行符以外的任意字符
^匹配字符串的開始位置
$匹配字符串的結束位置
*匹配前面的子表達式零次或多次
+匹配前面的子表達式一次或多次
?匹配前面的子表達式零次或一次
{n}匹配前面的子表達式恰好n次
{n,}匹配前面的子表達式至少n次
{n,m}匹配前面的子表達式至少n次,至多m次
[]匹配方括號中指定的任意一個字符
[^]匹配不在方括號中指定的任意一個字符
()標記一個子表達式的開始和結束位置
|表示或關系,匹配兩個或多個選項之一

2.3 預定義字符類

為了簡化常用字符類的定義,Java提供了一些預定義字符類:

預定義字符類等價表達式描述
\d[0-9]匹配一個數字字符
\D[^0-9]匹配一個非數字字符
\w[a-zA-Z_0-9]匹配一個單詞字符(字母、數字、下劃線)
\W[^a-zA-Z_0-9]匹配一個非單詞字符
\s[ \t\n\x0B\f\r]匹配一個空白字符(空格、制表符、換行符等)
\S[^ \t\n\x0B\f\r]匹配一個非空白字符

三、Java中正則表達式的基本用法

3.1 編譯正則表達式

在Java中使用正則表達式,首先需要將正則表達式字符串編譯為Pattern對象:

import java.util.regex.Pattern;public class RegexExample {public static void main(String[] args) {// 編譯正則表達式Pattern pattern = Pattern.compile("a.*c");}
}

3.2 創建Matcher對象并執行匹配

編譯后的Pattern對象用于創建Matcher對象,然后通過Matcher對象執行匹配操作:

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class RegexExample {public static void main(String[] args) {// 編譯正則表達式Pattern pattern = Pattern.compile("a.*c");// 創建Matcher對象Matcher matcher = pattern.matcher("abc");// 執行匹配操作boolean isMatch = matcher.matches();System.out.println("是否匹配: " + isMatch);  // 輸出: true}
}

3.3 常用的Matcher方法

  • matches():嘗試將整個輸入序列與模式匹配。
  • find():在輸入序列中查找下一個匹配的子序列。
  • group():返回當前匹配的子序列。
  • start():返回當前匹配的子序列的起始索引。
  • end():返回當前匹配的子序列的結束索引加1。

示例代碼:

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class RegexExample {public static void main(String[] args) {String input = "Hello, world! Hello, Java!";Pattern pattern = Pattern.compile("Hello");Matcher matcher = pattern.matcher(input);// 查找所有匹配項while (matcher.find()) {System.out.println("匹配到: " + matcher.group() + ", 起始位置: " + matcher.start() + ", 結束位置: " + matcher.end());}}
}

輸出結果:

匹配到: Hello, 起始位置: 0, 結束位置: 5
匹配到: Hello, 起始位置: 14, 結束位置: 19

四、正則表達式高級應用

4.1 分組與捕獲

使用圓括號()可以將正則表達式中的部分內容分組,每個分組可以被單獨捕獲和引用。分組編號從1開始,0表示整個匹配結果。

示例:匹配并提取郵箱地址中的用戶名和域名

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class GroupExample {public static void main(String[] args) {String email = "test.user@example.com";String regex = "([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})";Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(email);if (matcher.matches()) {System.out.println("完整匹配: " + matcher.group(0));  // 整個匹配結果System.out.println("用戶名: " + matcher.group(1));    // 第一組System.out.println("域名: " + matcher.group(2));      // 第二組}}
}

輸出結果:

完整匹配: test.user@example.com
用戶名: test.user
域名: example.com

4.2 反向引用

在正則表達式中,可以使用\n(n為數字)引用前面已經捕獲的分組。例如,匹配重復的單詞:

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class BackreferenceExample {public static void main(String[] args) {String text = "hello hello world world";String regex = "\\b(\\w+)\\s+\\1\\b";Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(text);while (matcher.find()) {System.out.println("重復的單詞: " + matcher.group());}}
}

輸出結果:

重復的單詞: hello hello
重復的單詞: world world

4.3 貪婪匹配與非貪婪匹配

  • 貪婪匹配:默認情況下,正則表達式的量詞(如*+{n,m})是貪婪的,會盡可能多地匹配字符。
  • 非貪婪匹配:在量詞后面加上?,可以將貪婪匹配轉換為非貪婪匹配,盡可能少地匹配字符。

示例:

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class GreedyVsNonGreedy {public static void main(String[] args) {String text = "<html><body><h1>Hello</h1></body></html>";// 貪婪匹配String greedyRegex = "<.*>";Pattern greedyPattern = Pattern.compile(greedyRegex);Matcher greedyMatcher = greedyPattern.matcher(text);if (greedyMatcher.find()) {System.out.println("貪婪匹配: " + greedyMatcher.group());}// 非貪婪匹配String nonGreedyRegex = "<.*?>";Pattern nonGreedyPattern = Pattern.compile(nonGreedyRegex);Matcher nonGreedyMatcher = nonGreedyPattern.matcher(text);while (nonGreedyMatcher.find()) {System.out.println("非貪婪匹配: " + nonGreedyMatcher.group());}}
}

輸出結果:

貪婪匹配: <html><body><h1>Hello</h1></body></html>
非貪婪匹配: <html>
非貪婪匹配: <body>
非貪婪匹配: <h1>
非貪婪匹配: </h1>
非貪婪匹配: </body>
非貪婪匹配: </html>

4.4 零寬斷言

零寬斷言用于在特定位置匹配某些內容,但不包含匹配的內容本身。Java支持四種零寬斷言:

斷言類型語法描述
正向先行斷言(?=pattern)匹配后面跟著pattern的位置
負向先行斷言(?!pattern)匹配后面不跟著pattern的位置
正向后行斷言(?<=pattern)匹配前面是pattern的位置
負向后行斷言(?<!pattern)匹配前面不是pattern的位置

示例:匹配所有以"ing"結尾的單詞

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class LookaroundExample {public static void main(String[] args) {String text = "running jumping swimming";String regex = "\\b\\w+(?=ing\\b)";Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(text);while (matcher.find()) {System.out.println("匹配到: " + matcher.group());}}
}

輸出結果:

匹配到: run
匹配到: jump
匹配到: swim

五、正則表達式在實際開發中的應用

5.1 表單驗證

正則表達式常用于表單驗證,確保用戶輸入的數據符合預期格式。

郵箱驗證
public static boolean isValidEmail(String email) {String regex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";return Pattern.matches(regex, email);
}
手機號驗證
public static boolean isValidPhone(String phone) {String regex = "^1[3-9]\\d{9}$";return Pattern.matches(regex, phone);
}
身份證號碼驗證
public static boolean isValidIdCard(String idCard) {String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$";return Pattern.matches(regex, idCard);
}

5.2 文本替換

使用正則表達式可以方便地進行文本替換操作。

替換HTML標簽
public static String removeHtmlTags(String html) {String regex = "<[^>]+>";return html.replaceAll(regex, "");
}
敏感詞過濾
public static String filterSensitiveWords(String text) {String[] sensitiveWords = {"敏感詞1", "敏感詞2", "敏感詞3"};String regex = String.join("|", sensitiveWords);return text.replaceAll(regex, "***");
}

5.3 文本分割

使用正則表達式可以按復雜規則分割文本。

按逗號或空格分割
public static String[] splitText(String text) {String regex = "[,\\s]+";return text.split(regex);
}
按數字分割
public static String[] splitByNumbers(String text) {String regex = "\\d+";return text.split(regex);
}

六、正則表達式性能優化

  1. 編譯一次,多次使用:避免在循環中重復編譯相同的正則表達式,應將編譯后的Pattern對象緩存并復用。
  2. 簡化正則表達式:復雜的正則表達式會降低匹配效率,盡量使用簡單、明確的表達式。
  3. 避免過度使用回溯:貪婪匹配和反向引用可能導致大量回溯,影響性能。
  4. 優先使用String類的方法:對于簡單的字符串操作,如startsWith()endsWith()indexOf()等,應優先使用String類的方法,比正則表達式效率更高。

七、常見問題與注意事項

  1. 轉義字符問題:在Java字符串中使用正則表達式時,需要注意轉義字符。例如,匹配點號.需要寫成\\.,匹配反斜杠\需要寫成\\\\
  2. 性能問題:復雜的正則表達式可能導致性能問題,特別是在處理大量數據時。
  3. 邊界問題:使用^$時要注意是否需要匹配整個字符串,還是只需要匹配部分內容。
  4. Unicode支持:Java默認支持Unicode字符,但在處理非ASCII字符時需要特別注意。

總結

正則表達式是Java中強大的文本處理工具,掌握正則表達式的基本語法和Java中的使用方法,對于提高字符串處理效率和開發質量至關重要。本文從基礎概念入手,詳細介紹了正則表達式的語法、Java中的API使用、高級應用場景以及性能優化等方面的內容,希望你在今后熟練使用盡量掌握。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82155.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82155.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82155.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

緩存擊穿、緩存雪崩、緩存穿透以及數據庫緩存雙寫不一致問題

在項目中&#xff0c;我們所需要的數據通常存儲在數據庫中&#xff0c;但是數據庫的數據保存在硬盤上&#xff0c;硬盤的讀寫操作很慢&#xff0c;為了避免直接訪問數據庫&#xff0c;我們可以使用 Redis 作為緩存層&#xff0c;緩存通常存儲在內存中&#xff0c;內存的讀寫速度…

可靈2.1 vs Veo 3:AI視頻生成誰更勝一籌?

在Google發布Veo 3幾天后,可靈顯然感受到了壓力,發布了即將推出的視頻模型系列可靈 2.1的早期體驗版。 據我了解,有三種不同的模式: 可靈 2.1 標準模式: 720p分辨率 僅支持圖像轉視頻(生成更快,一致性更好) 5秒視頻仍需20積分 可靈 2.1 專業模式: 1080p分辨率 僅在圖…

解決Docker存儲空間不足問題

虛擬機磁盤擴展實戰&#xff1a;解決Docker存儲空間不足問題 問題背景 在虛擬機中運行的Linux系統上&#xff0c;Docker服務因根分區空間不足而無法正常運行。初始狀態如下&#xff1a; [rootlocalhost ~]# df -h / 文件系統 容量 已用 可用 已用% 掛載點…

Redis 中如何保證緩存與數據庫的數據一致性?

在 Redis 中保證緩存與數據庫的數據一致性&#xff0c;需結合業務場景選擇以下策略&#xff1a; 核心策略總結 Cache Aside&#xff08;旁路緩存&#xff09;模式 讀操作&#xff1a;先查緩存&#xff0c;未命中則查數據庫并寫入緩存。寫操作&#xff1a;先更新數據庫&#xf…

晶振頻率穩定性:5G 基站與航天設備的核心競爭力

在當今科技飛速發展的時代&#xff0c;電子設備的性能和可靠性至關重要。晶振作為電子設備中的核心部件&#xff0c;為系統提供精確的時間和頻率基準。晶振的頻率穩定性直接影響著設備的整體性能&#xff0c;從日常生活中廣泛使用的智能手機、智能穿戴設備&#xff0c;到對精度…

PDFGear——完全免費且功能強大的PDF處理軟件

關鍵詞 &#xff1a;PDFGear、免費、跨平臺、多功能、OCR 概要 &#xff1a;PDFGear是一款完全免費且功能強大的PDF處理軟件&#xff0c;支持Windows、macOS、iOS和Android等多平臺使用。它集PDF閱讀、編輯、格式轉換、OCR識別及AI智能助手于一體&#xff0c;滿足用戶多樣化文檔…

【筆記】在 MSYS2(MINGW64)中正確安裝 Rust

#工作記錄 1. 環境信息 Windows系統: MSYS2 MINGW64當前時間: 2025年6月1日Rust 版本: rustc 1.87.0 (17067e9ac 2025-05-09) (Rev2, Built by MSYS2 project) 2. 安裝步驟 步驟 1: 更新系統包數據庫并升級已安裝的包 首先&#xff0c;確保我們的 MSYS2 系統是最新狀態。打…

WIN11+VSCODE搭建的c/c++環境調試報錯解決

解決調試報錯 前面win11vscode搭建的c/c環境&#xff0c;ctrlshiftB生成正常&#xff0c;cttlF5運行正常。今天打斷點逐步調試時報錯&#xff0c;提示找不到庫文件。解決方案如下&#xff1a; 下載mingw-w64源碼庫&#xff1a;&#xff08;兩種途徑&#xff09; 通過MSYS2 UC…

React項目在ios和安卓端要做一個漸變色背景,用css不支持,可使用react-native-linear-gradient

以上有個模塊是灰色逐漸到白的背景色過渡 如果是css&#xff0c;以下代碼就直接搞定 background: linear-gradient(180deg, #F6F6F6 0%, #FFF 100%);但是在RN中不支持這種寫法&#xff0c;那應該寫呢&#xff1f; 1.引入react-native-linear-gradient插件&#xff0c;我使用的是…

android-studio-2024.3.2.14如何用WIFI連接到手機(給數據線說 拜拜!)

原文&#xff1a;Android不用數據線就能調試真機的方法—給數據線說 拜拜&#xff01;&#xff08;adb遠程調試&#xff09; android-studio-2024.3.2.14是最新的版本&#xff0c;如何連接到手機&#xff0c;可用WIFI&#xff0c;可不用數據線&#xff0c;拜拜 第一步&#xf…

【前端】JS引擎 v.s. 正則表達式引擎

JS引擎 v.s. 正則表達式引擎 它們的轉義符都是\ 經過JS引擎會進行一次轉義 經過正則表達式會進行一次轉義在一次轉義中\\\\\的轉義過程&#xff1a; 第一個 \ (轉義符) 會“吃掉”第二個 \&#xff0c;結果是得到一個字面量的 \。 第三個 \ (轉義符) 會“吃掉”第四個 \&#x…

ReactHook有哪些

React 中常用的 Hooks 列表及用法 React Hooks 是 React 16.8 版本引入的一項重要特性&#xff0c;它極大地簡化和優化了函數組件的開發過程。以下是 React 中常用的 Hooks 列表及其詳細用法&#xff1a; 1. useState useState 是用于在函數組件中添加狀態的 Hook。通過調用…

【PyQt5】PyQt5初探 - 一個簡單的例程

PyQt5初探 - 一個簡單的例程 引言一、安裝配置二、使用2.1 PyQt5簡單例程2.2 與c Qt深入對比 三、相關教程 引言 PyQt5是一個比較流行的Python圖形用戶界面(GUI)庫&#xff0c;它基于Qt庫&#xff08;一個跨平臺的C庫&#xff0c;用于開發應用程序的圖形界面&#xff09;為Pyt…

圖文詳解Java并發面試題

文章目錄 1、并發與并行2、線程安全3、線程、進程、協程4、線程間通信5、線程創建方式6、8G內存創建的線程數7、普通Java程序含有的線程8、start()、run()9、線程調度、6種狀態、強制停止線程、上下文切換10、守護線程、用戶線程11、 volatile 、synchronized12、sleep() 、 wa…

飛牛fnNAS存儲空間模式詳解

目錄 一、NAS的存儲空間 二、多硬盤對NAS速度的提升原理 三、多硬盤對數據安全的提升原理 四、多硬盤對容量的提升原理 五、磁盤陣列模式 六、飛牛NAS支持的存儲模式 七、具體如何選擇存儲空間模式 在數字化時代,數據是個人和企業發展的核心資產,但面臨硬盤損壞、病毒…

OpenCv高階(二十)——dlib臉部輪廓繪制

文章目錄 一、人臉面部輪廓繪制代碼實現1、定義繪制直線段的函數2、定義繪制凸包輪廓的函數3、讀取輸入圖像4、初始化dlib的人臉檢測器5、使用檢測器在圖像中檢測人臉&#xff08;參數0表示不進行圖像縮放&#xff09;6、加載dlib的68點人臉關鍵點預測模型7、遍歷檢測到的每個人…

WEBSTORM前端 —— 第3章:移動 Web —— 第3節:移動適配

目錄 一、移動Web基礎 1.谷歌模擬器 2.屏幕分辨率 3.視口 4.二倍圖 二、適配方案 三、rem 適配方案 四、less 1.less – 簡介 2.less – 注釋 3.less – 運算 4.less – 嵌套 5.less – 變量 6.less – 導入 7.less – 導出 8.less – 禁止導出 五…

Altium Disigner(16.1)學習-原理圖繪制以及必要操作

一、下載軟件 通過網盤分享的文件&#xff1a;Altium Designer 16.zip 鏈接: https://pan.baidu.com/s/1uBHeoJJ-iA2tXw3NRjCcdA?pwd7c3h 提取碼: 7c3h 復制這段內容后打開百度網盤手機App&#xff0c;操作更方便哦 --來自百度網盤超級會員v5的分享 二、建立工程 添加proje…

AI煉丹日志-25 - OpenAI 開源的編碼助手 Codex 上手指南

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; Java篇&#xff1a; MyBatis 更新完畢目前開始更新 Spring&#xff0c;一起深入淺出&#xff01; 大數據篇 300&#xff1a; Hadoop&…

Redis:安裝與常用命令

&#x1f308; 個人主頁&#xff1a;Zfox_ &#x1f525; 系列專欄&#xff1a;Redis &#x1f525; 安裝 Redis 使?apt安裝 apt install redis -y?持遠程連接 修改 /etc/redis/redis.conf 修改 bind 127.0.0.1 為 bind 0.0.0.0 修改 protected-mode yes 為 protected-mo…