如何掌握 Java 正則表達式 的基本語法及在 Java 中的應用

正則表達式是一種用于匹配字符串的模式,在許多編程語言中廣泛使用。Java 正則表達式提供了強大的文本處理能力,能夠對字符串進行查找、替換、分割等操作。

一、正則表達式的基本語法

正則表達式由普通字符和特殊字符組成。普通字符包括字母、數字和標點符號,而特殊字符(也稱為元字符)則具有特殊意義,用于構建復雜的匹配模式。

1.1 普通字符

普通字符匹配自身。例如,正則表達式 abc 匹配字符串 "abc"

1.2 元字符

元字符是正則表達式的核心部分,用于定義復雜的匹配模式。常見的元字符包括:

  • .:匹配任意一個字符(除換行符)。
  • ^:匹配字符串的開始。
  • $:匹配字符串的結束。
  • *:匹配前一個字符零次或多次。
  • +:匹配前一個字符一次或多次。
  • ?:匹配前一個字符零次或一次。
  • []:定義字符類,匹配其中任意一個字符。
  • |:表示“或”操作。
  • ():用于分組和捕獲。
  • {}:用于限定重復次數。

1.3 轉義字符

有些字符在正則表達式中有特殊意義,如果要匹配這些字符本身,需要使用反斜杠 \ 進行轉義。例如,要匹配字符 .,應使用 \.

1.4 字符類

字符類用于定義一個字符集合,匹配其中任意一個字符。常用的字符類包括:

  • [abc]:匹配字符 abc
  • [a-z]:匹配任意一個小寫字母。
  • [A-Z]:匹配任意一個大寫字母。
  • [0-9]:匹配任意一個數字。
  • [^abc]:匹配除 abc 之外的任意一個字符。

1.5 預定義字符類

預定義字符類是一些常用字符類的簡寫形式,包括:

  • \d:匹配一個數字,等價于 [0-9]
  • \D:匹配一個非數字字符,等價于 [^0-9]
  • \w:匹配一個單詞字符(字母、數字或下劃線),等價于 [a-zA-Z0-9_]
  • \W:匹配一個非單詞字符,等價于 [^a-zA-Z0-9_]
  • \s:匹配一個空白字符(空格、制表符、換行符等),等價于 [ \t\n\x0B\f\r]
  • \S:匹配一個非空白字符,等價于 [^ \t\n\x0B\f\r]

1.6 邊界匹配符

邊界匹配符用于匹配字符串中的邊界位置,包括:

  • \b:匹配一個單詞邊界。
  • \B:匹配一個非單詞邊界。

1.7 限定符

限定符用于指定前一個字符或子模式的重復次數,包括:

  • *:匹配前一個字符零次或多次。
  • +:匹配前一個字符一次或多次。
  • ?:匹配前一個字符零次或一次。
  • {n}:匹配前一個字符恰好 n 次。
  • {n,}:匹配前一個字符至少 n 次。
  • {n,m}:匹配前一個字符至少 n 次,至多 m 次。

1.8 捕獲組和非捕獲組

捕獲組用于將匹配的子模式存儲起來,以便在后續操作中引用。非捕獲組用于對子模式進行分組,但不存儲匹配結果。

  • ():捕獲組。
  • (?:):非捕獲組。

1.9 零寬斷言

零寬斷言用于指定某個位置必須滿足的條件,包括:

  • (?=):正向先行斷言。
  • (?!:負向先行斷言。
  • (?<=):正向后行斷言。
  • (?<!:負向后行斷言。

二、Java 中的正則表達式 API

Java 提供了 java.util.regex 包來支持正則表達式處理,其中最重要的類是 PatternMatcher

2.1 Pattern

Pattern 類表示一個正則表達式的編譯表示。常用的方法包括:

  • compile(String regex):編譯給定的正則表達式。
  • matcher(CharSequence input):創建一個匹配器對象。

2.2 Matcher

Matcher 類用于對輸入字符串進行模式匹配操作。常用的方法包括:

  • matches():整個字符串是否與正則表達式匹配。
  • find():是否找到與正則表達式匹配的子字符串。
  • group():返回前一次匹配的子字符串。
  • replaceAll(String replacement):替換所有匹配的子字符串。
  • replaceFirst(String replacement):替換第一個匹配的子字符串。
  • lookingAt():是否從字符串的開頭開始匹配。

三、Java 正則表達式的常見用法

3.1 字符串匹配

3.1.1 完全匹配

要判斷字符串是否完全匹配某個正則表達式,可以使用 PatternMatcher 類:

String regex = "\\d+";
String input = "12345";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
boolean isMatch = matcher.matches();
System.out.println("完全匹配: " + isMatch);
3.1.2 子字符串匹配

要判斷字符串中是否包含某個正則表達式匹配的子字符串,可以使用 find 方法:

String regex = "\\d+";
String input = "hello 12345 world";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
boolean found = matcher.find();
System.out.println("包含子字符串匹配: " + found);

3.2 字符串替換

正則表達式可以用于替換字符串中的匹配部分。replaceAllreplaceFirst 方法用于替換所有匹配的子字符串或第一個匹配的子字符串:

String regex = "\\d+";
String input = "hello 12345 world";
String replacement = "number";
String result = input.replaceAll(regex, replacement);
System.out.println("替換結果: " + result);

3.3 字符串分割

正則表達式可以用于根據模式分割字符串。String 類提供了 split 方法:

String regex = "\\s+";
String input = "hello   world   java";
String[] parts = input.split(regex);
System.out.println("分割結果: " + Arrays.toString(parts));

3.4 捕獲組

捕獲組用于將匹配的子模式存儲起來,以便在后續操作中引用。可以使用 group 方法獲取捕獲組的內容:

String regex = "(\\d{3})-(\\d{2})-(\\d{4})";
String input = "123-45-6789";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {String part1 = matcher.group(1);String part2 = matcher.group(2);String part3 = matcher.group(3);System.out.println("捕獲組: " + part1 + ", " + part2 + ", " + part3);
}

3.5 零寬斷言

零寬斷言用于指定某個位置必須滿足的條件,但不包括在匹配結果中。以下示例展示了正向先行斷言:

String regex = "foo(?=bar)";
String input = "foobar";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {System.out.println("零寬斷言匹配: " + matcher.group());
}

四、Java 正則表達式高級應用

4.1 動態構建正則表達式

有時我們需要根據不同的輸入動態構建正則表達式。可以使用 StringBuilder 來拼接正則表達式:

String basePattern = "\\d";
int minDigits = 2;
int maxDigits = 4;
StringBuilder regex = new StringBuilder(basePattern);
regex.append("{").append(minDigits).append(",").append(maxDigits).append("}");
Pattern pattern = Pattern.compile(regex.toString());
String input = "123";
Matcher matcher = pattern.matcher(input);
boolean isMatch = matcher.matches();
System.out.println("動態構建正則表達式匹配: " + isMatch);

4.2 正則表達式中的嵌套組

嵌套組用于在一個捕獲組內再嵌套另一個捕獲組,以下示例展示了嵌套組的用法:

String regex = "(\\d{2})((\\d{2}))";
String input = "1234";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {String outerGroup = matcher.group(1);String nestedGroup = matcher.group(2);String innermostGroup = matcher.group(3);System.out.println("外部組: " + outerGroup + ", 嵌套組: " + nestedGroup + ", 最內部組: " + innermostGroup);
}

4.3 分組命名和引用

Java 7 引入了分組命名功能,可以給捕獲組命名,并通過名字引用:

String regex = "(?<areaCode>\\d{3})-(?<prefix>\\d{3})-(?<lineNumber>\\d{4})";
String input = "123-456-7890";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {String areaCode = matcher.group("areaCode");String prefix = matcher.group("prefix");String lineNumber = matcher.group("lineNumber");System.out.println("命名捕獲組: " + areaCode + ", " + prefix + ", " + lineNumber);
}

4.4 正則表達式的性能優化

在處理大型文本或復雜模式時,正則表達式的性能可能成為瓶頸。以下是一些性能優化建議:

  • 避免回溯:盡量避免使用可能導致大量回溯的模式,如重復的捕獲組。
  • 預編譯正則表達式:將正則表達式編譯為 Pattern 對象,并重用該對象,而不是每次都重新編譯。
  • 使用非捕獲組:在不需要捕獲匹配內容時,使用非捕獲組 (?:) 代替捕獲組 ()

4.5 正則表達式調試

調試正則表達式可能比較困難,可以使用在線工具(如 regex101)或集成開發環境(IDE)中的正則表達式調試功能來幫助理解和測試正則表達式。

掌握正則表達式可以大大提高文本處理的效率和靈活性,Java 提供的正則表達式 API 使得在程序中使用正則表達式變得簡單高效。

黑馬程序員免費預約咨詢

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

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

相關文章

通過 echo 命令向 /sys/class/gpio/export 寫入一個GPIO編號,但遇到 “Device or resource busy

通過 echo 命令向 /sys/class/gpio/export 寫入一個GPIO編號&#xff0c;但遇到 "Device or resource busy" 錯誤時&#xff0c;這通常意味著該GPIO引腳已經被其他驅動或用戶空間程序導出并使用了。 要解決這個問題&#xff0c;可以嘗試以下步驟&#xff1a; 檢查GP…

SpEL表達式使用方法

1 SpEL簡介 SpEL&#xff08;Spring Expression Language&#xff09;是一種用于在Spring框架中進行數據綁定和執行業務邏輯的表達式語言。Spring EL提供了一種簡潔、靈活和強大的方式來訪問對象的屬性、調用方法、執行運算和邏輯判斷等操作。 官方文檔&#xff1a;https://d…

C# 多線程:并發編程的利器

在現今日益復雜的軟件開發環境中&#xff0c;多線程編程已經成為提升應用程序性能和響應速度的關鍵技術。C# 作為一種現代、功能強大的編程語言&#xff0c;提供了豐富的多線程支持&#xff0c;使開發者能夠充分利用多核處理器和并行計算的優勢。本文將深入探討C#中的多線程編程…

網絡協議三

數據中心 一、DNS 現在網站的數目非常多&#xff0c;常用的網站就有二三十個&#xff0c;如果全部用 IP 地址進行訪問&#xff0c;恐怕很難記住 根 DNS 服務器 &#xff1a;返回頂級域 DNS 服務器的 IP 地址 頂級域 DNS 服務器&#xff1a;返回權威 DNS 服務器的 IP 地址 …

匯凱金業:貴金屬交易規則有哪些

貴金屬投資目前非常火熱&#xff0c;許多投資者從中獲得了可觀的收益。新手投資者在進入貴金屬市場及其交易之前&#xff0c;務必要了解清楚貴金屬的交易規則。了解規則和差異能幫助新手更好地進行貴金屬投資交易。下面我們以現貨類貴金屬為例&#xff0c;詳細說明貴金屬的交易…

一周學會Django5 Python Web開發 - Django5內置Auth認證系統-用戶修改密碼實現

鋒哥原創的Python Web開發 Django5視頻教程&#xff1a; 2024版 Django5 Python web開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili2024版 Django5 Python web開發 視頻教程(無廢話版) 玩命更新中~共計59條視頻&#xff0c;包括&#xff1a;2024版 Django5 Python we…

關于在 Ubuntu 下安裝配置和調優 FTP 服務器

今天我在阿貝云的免費服務器上部署測試FTP服務器&#xff0c;這個阿貝云真是個不錯的免費云服務器啊,配置雖然不高,但完全足夠搭建一個FTP服務器使用了。1核CPU、1G內存、10G硬盤、5M帶寬,對我這個喜歡折騰的家伙來說可太好用了。 首先,讓我簡單介紹下今天要用到的FTP服務器軟…

Mybatis雜記

group by查詢返回map類型 1,2 List<Map<String, Object>> getCount();xml: <select id"getCount" resultType"java.util.HashMap">SELECT company_id, ifnull(sum(count_a count_b),0) ctFROM test.com_countWHERE is_del 0 GROUP BY…

天氣數據集2-應用RNN做天氣預測

二、用循環神經網絡做天氣(溫度)預測 本項目是基于Pytorch的 RNN&GRU模型&#xff0c;用于預測未來溫度 數據集: https://mp.weixin.qq.com/s/08BmF4RnnwQ-jX5s_ukDUA 項目代碼: https://github.com/disanda/b_code/tree/master/Weather_Prediction RNN 模型本質是用于預…

MySQL(四)查詢

1、MySQL限性約束 —非空、唯一(自增)、主外鍵、檢查(MySQL存在但是不能用)。 約束主要完成對數據的校驗,保證數據庫數據的完整性;如果有相互依賴數據,保證該數據不被刪除。 1)常用五類約束 not null :非空約束,指定某列不為空。 unique:唯一約束,指定某列和幾列組…

基于springboot的-倉庫 管理系統【附:資料?文檔】

前言&#xff1a;我是源碼分享交流Coding&#xff0c;專注JavaVue領域&#xff0c;專業提供程序設計開發、源碼分享、 技術指導講解、各類項目免費分享&#xff0c;定制和畢業設計服務&#xff01; 免費獲取方式--->>文章末尾處&#xff01; 項目介紹&#xff1a; 管理員…

【VUE】el-table表格 實現滾動到底部加載更多數據

廢話不多說&#xff0c;直接上代碼 <template></template>部分代碼 <!-- 表格 --> <el-tableid"mytable"v-loading"listLoading"highlight-current-rowrow-key"project_id":data"tableData"border:reload"…

java中的三種拷貝方法

在Java編程中&#xff0c;理解深拷貝&#xff08;Deep Copy&#xff09;、淺拷貝&#xff08;Shallow Copy&#xff09;和引用拷貝&#xff08;Reference Copy&#xff09;是非常重要的。這三種拷貝方式涉及對象復制和內存管理。以下是對它們的詳細解釋&#xff1a; 1. 引用拷…

數字IC后端物理驗證PV | TSMC 12nm Calibre Base Layer DRC案例解析

基于TSMC 12nm ARM A55 upf flow后端設計實現訓練營將于6月中旬正式開班&#xff01;小班教學&#xff01;目前還有3個名額&#xff0c;招滿為止&#xff01;有需要可以私信小編 ic-backend2018報名。吾愛IC社區所有訓練營課程均為直播課&#xff01; 這個課程支持升級成雙核A…

服務器禁止密碼登陸

轉載請標明出處&#xff1a;https://blog.csdn.net/donkor_/article/details/139444224 文章目錄 一、前言二、編輯sshd_config文件三、重啟服務四、總結 一、前言 復雜的密碼&#xff0c;登陸服務器的時候&#xff0c;也是很不方便的。并且頻繁登陸&#xff0c;暴露給外界&am…

事件總線vueEvent

一個組件結束后要更新另一個組件數據&#xff0c;但是另一個組件和這個組件沒有上下級關系 在 Vue 中&#xff0c;非父子組件之間進行通信通常需要使用事件總線或者其他的全局事件管理器。在你的代碼片段中&#xff0c;vueEvent 似乎是一個事件總線對象&#xff0c;通過 emit 方…

c++ 里函數選擇的優先級:普通函數、模板函數、萬能引用,編譯器選擇哪個執行呢?

看大師寫的代碼時&#xff0c;除了在類里定義了 copy 構造函數&#xff0c;移動構造函數&#xff0c;還定義了對形參采取萬能引用的構造函數&#xff0c;因此有個疑問&#xff0c;這時候的構造函數優先級是什么樣的呢&#xff1f;簡化邏輯測試一下&#xff0c;如下圖&#xff0…

如何實現JavaScript中的寄生組合式繼承?

在JavaScript中&#xff0c;寄生組合式繼承是一種繼承機制&#xff0c;它結合了寄生式繼承和組合繼承的特點。其核心思想是通過構造函數來繼承屬性&#xff0c;同時通過原型鏈來繼承方法。以下是實現寄生組合式繼承的基本步驟&#xff1a; 首先定義一個輔助函數 inheritProtot…

Pygame:新手指南與入門教程

在游戲開發領域,pygame 是一個廣受歡迎的 Python 庫,它提供了開發二維游戲的豐富工具和方法。這個庫讓開發者可以較少地關注底層圖形處理細節,更多地專注于游戲邏輯和玩法的實現。本文將詳細介紹 pygame,包括其安裝過程、基本概念、主要功能和一個簡單游戲的開發流程。 一…

【Vue】路由的封裝抽離

問題&#xff1a;所有的路由配置都在main.js中合適嗎&#xff1f; 目標&#xff1a;將路由模塊抽離出來。 好處&#xff1a;拆分模塊&#xff0c;利于維護 路徑簡寫&#xff1a; 腳手架環境下 指代src目錄&#xff0c;可以用于快速引入組件 完整代碼 router/index.js // 但…