JavaSe系列二十七: Java正則表達式

正則表達式

  • 為什么要學習正則表達式
  • 再提幾個問題
  • 解決之道-正則表達式
  • 正則表達式基本介紹
    • 介紹
  • 正則表達式底層實現
    • 實例分析
  • 正則表達式語法
    • 基本介紹
    • 元字符-轉義號 \\\\
    • 元字符-字符匹配符
    • 元字符-選擇匹配符
    • 元字符-限定符
    • 元字符-定位符
    • 分組
    • 非貪婪匹配
  • 應用實例
    • 對字符串進行如下驗證
  • 正則表達式三個常用類
  • 分組, 捕獲, 反向引用
    • 提出需求
    • 介紹
    • 看幾個小案例
    • 經典的結巴程序
  • String類中使用正則表達式
    • 替換功能
    • 判斷功能
    • 分割功能
  • 本章作業

在這里插入圖片描述

為什么要學習正則表達式

1.新建java項目chapter27

在這里插入圖片描述

2.新建E:\idea_project\zzw_javase\idea_java_project\chapter27\src\com\zzw\regexp\Regexp_.java

public class Regexp_ {public static void main(String[] args) {String content = "私有地址(Private address)屬于非注冊地址,專門為組織機構內部使用。\n" +"以下列出留用的內部私有地址\n" +"A類 10.0.0.0--10.255.255.255\n" +"B類 172.16.0.0--172.31.255.255\n" +"C類 192.168.0.0--192.168.255.255";//1.先創建一個Pattern對象(模式對象), 可以理解成就是一個正則表達式對象//(1)提取文章中所有的英文單詞 -> 傳統方法, 使用遍歷, 代碼量大Pattern pattern = Pattern.compile("[a-zA-Z]+");//(2)提取文章中所有的數字//Pattern pattern = Pattern.compile("[0-9]+");//(3)提取文章中所有的英文單詞和數字//Pattern pattern = Pattern.compile("[a-zA-Z0-9]+");//2.創建一個匹配器對象//  matcher 匹配器按照 pattern(模式/樣式) 到content中去查找/匹配Matcher matcher = pattern.matcher(content);//3.開始循環匹配while (matcher.find()) {//匹配內容/文本, 放到matcher.group(0)System.out.println("找到: " + matcher.group(0));}}
}

3.結論:正則表達式是處理文本的利器.

再提幾個問題

1.給你一個字符串(或文章), 請你找你所有四個數字連在一起的子串?

2.給你一個字符串(或文章), 請你找出所有四個數字連在一起的子串, 并且這四個數字要滿足: 第一位與第四位相同, 第二位與第三位相同. 比如: 1221, 3443.

3.請驗證輸入的郵件, 是否符合電子郵件格式.

4.請驗證輸入的手機號, 是否符合手機號格式.

解決之道-正則表達式

1.為了解決上述問題, Java提供了正則表達式技術, 專門用于處理類似文本問題.

2.簡單地說: 正則表達式是對字符串執行模式匹配的技術.

3.正則表達式: regular expression => RegExp

正則表達式基本介紹

介紹

1.一個正則表達式, 就使用某種模式去匹配字符串的一個公式. 很多人認為它們看上去比較古怪而且復雜所以不敢去使用. 不過, 經過練習后, 就覺得這些復雜的表達式寫起來還是相當簡單的, 而且, 一旦你弄懂它們, 你就能把數小時辛苦而且易錯的文本處理工作縮短在幾分鐘(甚至幾秒鐘)內完成.

2.這里特別強調, 正則表達式不是只有java才有, 實際上很多編程語言都支持正則表達式進行字符串操作!

正則表達式底層實現

實例分析

需求: 為了讓大家對正則表達式底層實現有一個直觀的印象, 給大家舉個實例. 給你一段字符串(文本), 請找出所有四個數字連在一起的子串. 比如, 應該找到 2000, 1998, 2012, 2020.

分析底層實現

1.新建src/com/zzw/regexp/RegTheory.java

//分析java正則表達式的底層實現
public class RegTheory {public static void main(String[] args) {String content = "1998 年 12 月 8 日,第二代 Java 平臺的企業版 J2EE 發布。1999 年 6 月,Sun 公司發布了\" +\n" +"\"第二代 Java 平臺(簡稱為 Java2)的 3 個版本:J2ME(Java2 Micro Edition,Java2 平臺的微型\" +\n" +"\"版),應用于移動、無線及有限資源的環境;J2SE(Java 2 Standard Edition,Java 2 平臺的\" +\n" +"\"標準版),應用于桌面環境;J2EE(Java 2Enterprise Edition,Java 2 平臺的企業版),應\" +\n" +"\"用 3443 于基于 Java 的應用服務器。Java 2 平臺的發布,是 Java 發展過程中最重要的一個\" +\n" +"\"里程碑,標志著 Java 的應用開始普及 9889 \"";//目標: 匹配所有四個數字//說明//1. \\d表示一個任意的數字String regStr = "(\\d\\d)(\\d\\d)";//2. 創建模式對象[即正則表達式對象]Pattern pattern = Pattern.compile(regStr);//3. 創建匹配器//說明: 創建匹配器 matcher, 按照正則表達式的規則 去匹配 content 字符串Matcher matcher = pattern.matcher(content);//4. 開始循環匹配/*** matcher.find() 完成的任務(這里考慮分組)* 什么是分組, 比如 (\d\d)(\d\d), 正則表達式中有()表示分組, 第1個()表示第1組, 第2個()表示第2組...* 1.根據指定的規則, 定位滿足規則的子字符串(比如(19)(98))* 2.找到后, 將子字符串的開始與結束的索引, 記錄到 matcher 對象的屬性 int[] groups;*   (1) groups[0] = 0, 把該子字符串(1998)結束的索引+1 的值記錄到 groups[1] = 4*   (2) 記錄第1組()匹配到的字符串 groups[2] = 0, gourps[3] = 2*   (3) 記錄第2組()匹配到的字符串 groups[4] = 2, groups[5] = 4*   (4) 如果有更多的分組...* 3.同時記錄oldLast的值為 子字符串的結束的索引+1的值, 即 4, 即下次執行find時, 就從 4 開始匹配** matcher.group(0)分析* 源碼:* public String group(int group) {*     if (first < 0)*         throw new IllegalStateException("No match found");*     if (group < 0 || group > groupCount())*         throw new IndexOutOfBoundsException("No group " + group);*     if ((groups[group*2] == -1) || (groups[group*2+1] == -1))*         return null;*     return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();* }* 1.根據groups[0]=0 和 groups[1]=4 記錄的位置, 從content開始到截取子字符串返回* , 就是[0,4) 包含0但是不包含索引為35的位置** 2.如果再次指向 find 方法, 仍然按上面分析來執行*/while (matcher.find()) {/*** 小結* 1.如果正則表達式有(), 即分組* 2.去除匹配的字符串規則如下* (1)group(0) 表示匹配到的子字符串* (2)group(1) 表示匹配到的子字符串的第一組子串* (3)group(2) 表示匹配到的子字符串的第二組子串* (4)分組的數不能越界...*/System.out.println("找到: " + matcher.group(0));System.out.println("第1組()匹配到的值=" + matcher.group(1));System.out.println("第2組()匹配到的值=" + matcher.group(2));}}
}

在這里插入圖片描述
在這里插入圖片描述

正則表達式語法

基本介紹

如果要想靈活地運用正則表達式,必須了解其中各種元字符的功能,元字符從功能上大致分為:

1.限定符
2.選擇匹配符
3.分組組合和反向引用符
4.特殊字符
5.字符匹配符
6.定位符

元字符-轉義號 \\

\\ 符號 說明: 在我們使用正則表達式去檢索某些特殊字符的時候,需要用到轉義符號, 否則檢索不到結果,甚至會報錯的。

案例:用 $ 去匹配 “abc$(” 會怎樣?

提示: 在Java正則表達式中, 兩個 \\ 代表其它語言中的一個 \

1.新建src/com/zzw/regexp/RegExp02.java

//演示轉義字符的使用
public class RegExp02 {public static void main(String[] args) {String content = "abc$(a.bc(123( )";//匹配 ( => \\(//String regStr = "\\(";//匹配 . => \\.//String regStr = "\\.";//匹配 3個數字 => \\d\\d\\d//String regStr = "\\d\\d\\d";String regStr = "\\d{3}";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}}
}

2.需要用到轉移符號的字符有以下: . * + ( ) $ / \ ?[ ] ^ { }

元字符-字符匹配符

符號含義示例解釋
[ ]可接收的字符列表[abcd]a、b、c、d中的任意一個字符
[ ^ ]不可接收的字符列表[^abcd]除a、b、c、d外的任意一個字符(包括數字和特殊符號)
-連字符A-Z任意單個大寫字母
符號含義示例解釋匹配輸入
.匹配除 \n 以外的任何字符a..b以a開頭,b結尾,中間包括2個
任意字符的長度為4的字符串
accb, a22b, a$#b
\\d匹配單個數字字符, 相當于[0-9]\d{3}(\d)?包含3個或4個數字的字符串123,1234
\\D匹配單個非數字字符, 相當于[^0-9]\\D(\\d)*以單個非數字字符開頭,后接
任意個數字字符串
e1231, E332
\\w匹配單個數字, 大小寫字母字符,相當于[0-9a-zA-Z]\d{3}\w{4}以3個數字字符開頭的
長度為7的數字字符串
123qwer, 12345qw
\\W匹配單個非數字,大小寫字母字符,相當于[^0-9a-zA-Z]\\W+\\d{2}以至少一個非數字字母開頭,2個
數字字符結尾的字符串
#12, #$#@32

1.新建src/com/zzw/regexp/RegExp03.java

//演示字符匹配符的使用
public class RegExp03 {public static void main(String[] args) {String content = "a11c8abc _ABCy @";//String regStr = "[a-z]";//匹配a-z之間任意一個字符//String regStr = "[A-Z]";//匹配A-Z之間任意一個字符//String regStr = "abc";//匹配abc字符串[默認區分大小寫]//(?i) 是一個模式修飾符,表示不區分大小寫(ignore case)//String regStr = "(?i)abc";//匹配abc字符串[不區分大小寫]//String regStr = "[0-9]";//匹配0-9之間任意一個字符//String regStr = "[^a-z]";//匹配不在a-z之間任意一個字符//String regStr = "[^0-9]";//匹配不在0-9之間任意一個字符//String regStr = "[abcd]";//匹配abcd中任意一個字符//String regStr = "\\D";//匹配不在0-9的任意一個字符//String regStr = "\\w";//匹配一個大小寫英文字母,數字,下劃線//String regStr = "\\W";//匹配,等價于[^0-9a-zA-Z]//String regStr = "\\s";//\\s 匹配任何空白字符(空格,制表符等)//String regStr = "\\S";//\\S 匹配任何非空白字符,和\\s相反String regStr = ".";// . 匹配除\n之外的所有單個字符, 如果要匹配本身則使用\\.//注意: 當創建Pattern對象時, 指定 Pattern.Pattern pattern = Pattern.compile(regStr, Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}}
}

注意:
String regStr = "."只會匹配一個字符
String regStr = ".*"則會匹配任意個字符

元字符-選擇匹配符

在匹配某個字符串的時候是選擇性的,即:即可以匹配這個,有可以匹配那個,這時需要使用到 選擇匹配符號 |

1.新建src/com/zzw/regexp/RegExp04.java

//演示選擇匹配符的使用
public class RegExp04 {public static void main(String[] args) {String content = "abcde趙志偉love趙培竹";String regStr = "趙|偉|培|竹";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}}
}

輸出
找到: 趙
找到: 偉
找到: 趙
找到: 培
找到: 竹

元字符-限定符

用于指定其前面的字符和組合連續出現多少次

符號含義示例解釋匹配輸入
*指定字符重復0次或n次(無要求,零到多)(abc)*僅包含任意個abc的字符串,
等效于\w*
abc, abcabca
+指定字符重復1次或n次(至少一次, 一到多)m+(abc)*以至少一個m開頭, 后接
任意個abc的字符串
m,mabc,mabcabc
?指定字符重復0次或1次(最多一次, 零到一)m+abc?以至少一個m開頭,
后接ab或abc的字符串
mab, mabc,mmab, mmabc
{n}只能輸入n個字符[abcd]{3}由abcd中任意字母組成的
長度為3的字符串
aac, dbc, adc
{n,}至少指定n個匹配[abcd]{3,}由abcd中任意字母組成的
長度不小于3的字符串
aab, dbc, abcada
{n,m}指定至少n個但不多于m個匹配[abcd]{3,5}由abcd中任意字母組成的長度
不小于3,不大于5的字符串
abc, abcd, abaaa, bbbbb

1.新建src/com/zzw/regexp/RegExp05.java

//演示限定符的使用
public class RegExp05 {public static void main(String[] args) {String content = "a211111aaaaaahello";//String regStr = "a{3}";//匹配 aaa//String regStr = "1{4}";//匹配 1111//String regStr = "\\d{2}";//匹配 兩位任意數字字符//細節: java匹配默認是貪婪匹配, 即盡可能匹配多的//String regStr = "a{3,4}";//表示匹配 aaa或者aaaa//String regStr = "1{4,5}";//表示匹配 1111或11111//String regStr = "\\d{2,5}";//表示匹配 兩位任意數字字符 或者三位,四位,五位//String regStr = "1+";//表示匹配1個或多個1//String regStr = "\\d+";//表示匹配一個數字或多個數字//String regStr = "1*";//表示匹配0個或多個1//演示?的使用, 遵守貪婪匹配String regStr = "a1?";//匹配 a或者a1Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}}
}

元字符-定位符

定位符, 規定要匹配的字符串出現的位置, 比如在字符串的開始還是在結束的位置, 必須掌握.

符號含義示例解釋匹配輸入
^指定起始字符^[0-9]+[a-z]*以至少一個數字開頭, 后接
任意個小寫字符的字符串
123,6aa,555edf
$指定結束字符^[0-9]\-[a-z]+$以一個數字開頭后接連字符"="
并以至少一個小寫字母結尾的字符串
1-a
\\b匹配目標字符串的邊界wei\\b這里說的字符串的邊界指的是子串間有空格
或者是目標字符串的結束位置
\\B匹配目標字符串的非邊界wei\\B和\\b的含義正好相反
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               1.新建`src/com/zzw/regexp/RegExp06.java`
//演示定位符的使用
public class RegExp06 {public static void main(String[] args) {String content = "hanshunping sphan nnhan";//String content = "123-abc";//以至少一個數字字符開頭, 后接任意個小寫字母//String regStr = "^[0-9]+[a-z]*$";//以至少一個數字字符開頭, 以至少一個小寫字母結束(體現了貪婪匹配)//String regStr = "^[0-9]+\\-[a-z]+$";//表示匹配邊界的han// (這里的邊界是指: 被匹配的字符串最后, 也可以是空格的子字符串的最后)/*找到: han找到: han*///String regStr = "han\\b";//和\\b的含義剛剛相反/*找到: han找到: han*/String regStr = "\\Bhan";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}}
}

分組

常用分組構造形式說明
(pattern)非命名捕獲. 捕獲匹配的子字符串. 編號為零的第一個捕獲是由整個正則表達式模式匹配的文本.
其它捕獲結果則根據左括號的順序從1開始自動編號.
(?<name>pattern)命名捕獲, 將匹配的子字符串捕獲到一個組名稱或編號名稱中. 用于name的字符串
不能包含任何標點符號, 并且不能以數字開頭, 可以使用單引號替代尖括號. 例如 (?‘name’)
(?:pattern)匹配 pattern 但不捕獲該匹配的子表達式, 即它是一個非捕獲匹配, 不存儲供以后使用的匹配.
這對于用"or"字符 (|) 組合模式部件的情況很有用.
例如: 'industr(?:y|ies) 是比 industry|industries更經濟的表達式.
(?=pattern)它是一個非捕獲匹配. 例如: Windows (?=95|98|NT|2000) 匹配 Windows 2000 中的 Windows,
但不匹配 Windows 3.1 中的 Windows
(?!pattern)該表達式匹配不處于匹配 pattern 的字符串的起始點的搜索字符串. 它是一個非捕獲匹配.
例如, Windows (?!95|98|NT|2000)
匹配 Windows 3.1 中的 Windows, 但不匹配 Windows 2000 中的 Windows

1.新建src/com/zzw/regexp/RegExp07.java

public class RegExp07 {public static void main(String[] args) {String content = "zhaozhiwei s2012 nihao1015zhao";//下面就是非命名分組//說明//1. matcher.group(0) 得到匹配到的字符串//2. matcher.group(1) 得到匹配到的字符串的第1個分組內容//3. matcher.group(2) 得到匹配到的字符串的第2個分組內容//String regStr = "(\\d\\d)(\\d\\d)";//匹配4個數字的字符串//命名分組: 即可以給分組取名String regStr = "(?<g1>\\d\\d)(?<g2>\\d\\d)";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));System.out.println("第1個分組內容: " + matcher.group(1));System.out.println("第2個分組內容: " + matcher.group(2));System.out.println("第一個分組內容[通過組名]: " + matcher.group("g1"));System.out.println("第二個分組內容[通過組名]: " + matcher.group("g2"));}}
}

2.新建src/com/zzw/regexp/RegExp08.java

//演示非捕獲分組, 語法比較奇怪
public class RegExp08 {public static void main(String[] args) {String content = "hello 周杰倫歌手 hello 周杰倫導演 hello 周杰倫老師 hello 周杰倫演員 hello 周杰倫baby";//找到: 周杰倫歌手, 周杰倫導演, 周杰倫老師, 周杰倫演員, 周杰倫baby//String regStr = "周杰倫歌手|周杰倫導演|周杰倫老師周杰倫演員|周杰倫baby";//下面的寫法可以等價非捕獲分組. 注意: 不能 matcher.group(1)//String regStr = "周杰倫(?:歌手|導演|老師|演員|baby)";//找到 周杰倫 這個關鍵詞, 但是要求只是查找周杰倫歌手, 周杰倫演員 中包含的周杰倫//下面也是非捕獲分組, 不能使用 matcher.group(1)//String regStr = "周杰倫(?=歌手|演員)";//找到 周杰倫 這個關鍵詞, 但是要求只是查找 不是 (周杰倫歌手 和 周杰倫演員) 中包含的周杰倫//下面也是非捕獲分組, 不能使用 matcher.group(1)String regStr = "周杰倫(?!歌手|演員)";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}}
}

在這里插入圖片描述

非貪婪匹配

1.新建com.zzw.regexp.RegExp09.java

public class RegExp09 {public static void main(String[] args) {String content = "hello1111111 ok";//String regStr = "\\d+";//默認是貪婪匹配String regStr = "\\d+?";//非貪婪匹配Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}}
}

應用實例

對字符串進行如下驗證

1.漢字
2.郵政編碼. 要求: 是1-9開頭的一個六位數. 比如:123890
3.QQ號碼. 要求:是1-9開頭的一個(5位數-10位數) 比如: 12345, 123456789, 978964140
4.手機號碼. 要求: 必須以13, 14, 15, 18開頭的11位數, 比如 13031758275
5.URL : 比如
https://www.bilibili.com/video/BV16Z4y1i7vv/?p=7&spm_id_from=pageDriver&vd_source=03325a87946ce23102fa48daa830127a

新建com.zzw.regexp.RegExp10.java

//正則表達式應用實例
public class RegExp10 {public static void main(String[] args) {//漢字//String content = "趙志偉";//String regStr = "^[\\u0391-\\uffe5]+$";//郵政編碼//要求: 是1-9開頭的一個六位數. 比如:123890//String content = "123890";//String regStr = "^[1-9]\\d{5}$";//QQ號碼//要求:是1-9開頭的一個(5位數-10位數) 比如: 12345, 123456789, 978964140//String content = "978964140";//String regStr = "^[1-9]\\d{4,9}$";//手機號碼//要求: 必須以13, 14, 15, 18開頭的11位數, 比如 13031758275String content = "13031758275";String regStr = "^(?:13|14|15|18)\\d{9}$";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);if (matcher.find()) { System.out.println("滿足格式"); } else { System.out.println("不滿足格式"); }}
}

新建com.zzw.regexp.RegExp11.java

//正則表達式應用實例
public class RegExp11 {public static void main(String[] args) {String content = "https://www.bilibili.com/video/BV16Z4y1i7vv/?p=7&spm_id_from=pageDriver&vd_source=03325a87946ce23102fa48daa830127a";/*** 思路* 1.先確定 url 的開始部分 http(?:s|)://* 2.然后通過 ([\\w-]+\.)+[\\w-]+, 匹配 www.bilibili.com* 3.通過 (\\/[\\w-?=&/%.#]*)? 匹配 /video/BV16Z4y1i7vv/?p=7&spm_id_from=pageDriver&vd_source=03325a87946ce23102fa48daa830127a*/String regStr = "(http(?:s|)://)?([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}//這里如果使用 Pattern 的 matcheres 整體匹配 比較簡潔    System.out.println(Pattern.matches(regStr, content));}
}

正則表達式三個常用類

java.util.regex 包主要包括以下三個類 Patterh 類, Matcher類 和 PatternSyntaxException.

●Pattern類
Pattern對象是一個正則表達式對象. Pattern類沒有公共構造方法, 要創建一個 Pattern對象, 需調用其公共靜態方法, 返回一個 Pattern對象. 該方法接受一個正則表達式作為它的第一個參數. 比如:Pattern pattern = Pattern.compile(regStr)

●Matcher類
Matcher 對象是對輸入字符串進行解釋和匹配的引用. 與Pattern類一樣, Matcher也沒有公共構造方法, 需要調用 Pattern對象的matcher方法來獲一個Matcher對象.

●PatternSyntaxException
PatternSyntaxException是一個非強制異常類, 它表示一個正則表達式模式中的語法錯誤.

1.新建com.zzw.regexp.PatternMethod.java

//演示 matches 方法, 用于整體匹配, 在驗證輸入的字符串是否滿足條件時使用
public class PatternMethod {public static void main(String[] args) {String content = "hello world 趙志偉 虛擬世界";//String regStr = "hello";String regStr = "hello.*";boolean matches = Pattern.matches(regStr, content);System.out.println("整體匹配: " + matches);}
}

2.新建com.zzw.regexp.MatcherMethod.java

//Matcher類的常用方法
public class MatcherMethod {public static void main(String[] args) {String content = "hello tom hello jack hello king hello queen";String regStr = "hello";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("==================");System.out.println(matcher.start());System.out.println(matcher.end());System.out.println("找到: " + content.substring(matcher.start(), matcher.end()));}//整體匹配方法, 常用于 去校驗某個字符串是否滿足某個規則System.out.println("整體匹配: " + matcher.matches());//完成如果 content 有 king 替換成 國王regStr = "king";pattern = Pattern.compile(regStr);matcher = pattern.matcher(content);//注意: 返回的字符串才是替換后的字符串, 原來的 content 不變化String newContent = matcher.replaceAll("國王");System.out.println("替換后的字符串: " + newContent);System.out.println("content: " + content);}
}

分組, 捕獲, 反向引用

提出需求

請看下面問題:

給你一段文本, 請你找出四個數字連在一起的字串, 并且這四個數字要滿足第1位與第4位相同, 第2位與第3位相同, 比如 1221, 5775…

介紹

(\\d\\d)(\\d\\d)
要滿足前面的問題, 我們需要了解正則表達式的幾個概念

1.分組
我們可以用圓括號組成一個比較復雜的匹配模式, 那么一個圓括號的部分我們看作是一個子表達式/一個分組.

2.捕獲
把正則表達式中子表達式/分組匹配的內容, 保存到內存中以數字編號或顯示命名的組里, 方便后面引用. 從左向右, 以分組的左括號為標志, 第一個出現的分組的組號為1, 第二個為2, 依此類推, 組0代表的是整個正則式.

3.反向引用
圓括號的內容被捕獲后, 可以在這個括號后被使用, 從而寫出一個比較實用的匹配模式, 這個我們稱為反向引用, 這種引用既可以使在正則表達式內部, 也可以是在正則表達式外部, 內部反向引用 \分組號, 外部反向引用 $分組號.

看幾個小案例

1.要匹配兩個連續的相同數字: (\\d)\\1
2.要匹配五個連續的相同數字: (\\d)\\1{4}
3.要匹配個位與千位相同, 十位與百位相同的數 (\\d)(\\d)\\2\\1

●思考題
請在字符串中檢索商品編號, 形式如: 12321-333999111 這樣的號碼, 要求滿足前面是一個五位數, 然后一個-號, 然后是一個九位數, 連續的每三位要相同.

1.新建com.zzw.regexp.RegExp12.java

public class RegExp12 {public static void main(String[] args) {String content = "1232112321-333666999321412";String regStr = "\\d{5}\\-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group(0));}}
}

經典的結巴程序

把類似 “我…我要…學學學學…編程java!” 通過正則表達式 修改成 “我要學編程java!”

1.新建com.zzw.regexp.RegExp13.java

public class RegExp13 {public static void main(String[] args) {String content = "我....我要....學學學學....編程java!";//1.去掉所有的 .String regStr = "\\.";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);String newContent = matcher.replaceAll("");System.out.println("newContent=" + newContent);//2.去掉連續重復的字regStr = "(.)\\1+";pattern = Pattern.compile(regStr);matcher = pattern.matcher(newContent);newContent = matcher.replaceAll("$1");System.out.println("newContent=" + newContent);}
}

String類中使用正則表達式

替換功能

public String replaceAll(String regex, String replacement)

判斷功能

public boolean matches(String regex) 使用 Pattern 和 Matcher 類

分割功能

public String[] split(String regex)

1.新建com.zzw.regexp.StringReg.java

public class StringReg {public static void main(String[] args) {//使用正則表達式, 將 jdk1.3 和 jdk1.4 替換成 jdkString content = "馬踏飛燕jdk1.3 hello,worldjdk1.4 hello";String regStr = "jdk1\\.(?:3|4)";String newContent = content.replaceAll(regStr, "jdk");System.out.println("newContent=" + newContent);//要求: 驗證一個手機號, 要求必須使以 138 139 開頭的content = "13812345678";if (content.matches("^13(?:8|9)\\d{8}$")) {System.out.println("驗證成功");} else {System.out.println("驗證失敗");}//要求: 按照 # 或者 - 或者 ~ 或者 數字 來分割字符串content = "趙志偉#山東省-濟寧市~泗水縣33泗張鎮~付山莊村";String[] split = content.split("#|-|~|\\d+");for (String string : split) {System.out.println(string);}}
}

本章作業

1.驗證電子郵件格式是否合法. 規定電子郵件規則是
①只能有一個@
②@前面是用戶名, 可以是a-z A-Z 0-9 _ - 字符
③@后面是域名, 并且域名只能是英文字母, 比如 sohu.com 或者 tsinghua.org.cn
④寫出對應的正則表達式, 驗證輸入的字符串是否滿足規則

新建com.zzw.homework.Homework01.java

public class Homework01 {public static void main(String[] args) {String content = "978964140@qq.com";String regStr = "[\\w_-]+@([a-zA-Z]+\\.)+[a-zA-Z]+";if (content.matches(regStr)) {System.out.println("符合要求");} else {System.out.println("不符合要求");}}
}

2.要求驗證是不是整數或者小數. 提示: 這個題要考慮整數和負數.
比如: 123, -123, 34.53, -21.54, 0.99, -0.43 等.

新建com.zzw.homework.Homework02.java

public class Homework02 {public static void main(String[] args) {String content = "-0.12";//判斷是不是整數String regStr = "^(?:|\\+|-)[1-9]\\d*$";if (content.matches(regStr)) {System.out.println("是整數");} else {System.out.println("不是整數");}//判斷是不是小數regStr = "^(?:|\\+|-)\\d+\\.\\d+$";if (content.matches(regStr)) {System.out.println("是小數");} else {System.out.println("不是小數");}//判斷是不是整數或小數regStr = "^[+-]?([1-9]\\d*|0)(\\.\\d+)?$";if (content.matches(regStr)) {System.out.println("是整數或小數");} else {System.out.println("不是整數或小數");}
}

3.對一個url進行解析
http://www.bilibili.com:8080/abc/index.html
①要求得到協議是什么? http
②域名是什么? www.sohu.com
③端口是什么? 8080
④文件名是什么? index.html

新建com.zzw.homework.Homework03.java

public class Homework03 {public static void main(String[] args) {String content = "http://www.bilibili.com:8080/abc/index.html";String regStr = "^((?<g1>http(?:s|))://)?(?<g2>([\\w-]+\\.)+[\\w-]+):(?<g3>\\d+)/\\w+/(?<g4>([\\w-]+\\.)+[\\w-]+)$";Pattern pattern = Pattern.compile(regStr);Matcher matcher = pattern.matcher(content);while (matcher.find()) {System.out.println("找到: " + matcher.group("g1"));System.out.println("找到: " + matcher.group("g2"));System.out.println("找到: " + matcher.group("g3"));System.out.println("找到: " + matcher.group("g4"));}}
}

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

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

相關文章

學習筆記——動態路由——OSPF聚合(匯總)

十一、OSPF聚合(匯總) 1、路由聚合(匯總) 路由匯總是一種重要的思想&#xff0c;在大型的項目中是必須考慮的一個重點事項。隨著網絡的規模越來越大&#xff0c;網絡中的設備所需維護的路由表項也就會越來越多&#xff0c;路由表的規模也就會逐漸變大&#xff0c;而路由表是需…

React中的useMemo和memo

引言 React是一個聲明式的JavaScript庫&#xff0c;用于構建用戶界面。在開發過程中&#xff0c;性能優化是一個重要的方面。useMemo和memo是React提供的工具&#xff0c;用于幫助開發者避免不必要的渲染和計算&#xff0c;從而提升應用性能。 問題背景 在React應用中&#…

實現antd designable平臺的組件拖拽功能

平臺&#xff1a;designable設計器 github&#xff1a;designable 目錄 1 背景2 技術棧3 組件拖拽和放置3.1 類型定義3.2 拖拽3.3 放置 1 背景 由于業務需求&#xff0c;我們需要實現designable平臺的一個簡易版的組件拖拽功能。 #mermaid-svg-QrxSDGe9YyGG3LbQ {font-family:…

【Unity2D 2022:UI】制作角色血條

一、創建血底UI 1. 創建畫布&#xff08;Canvas&#xff09; 2. 在畫布上添加血底圖像&#xff08;Image&#xff09;子物體 二、編輯血底UI 1. 將血底圖片拖入源圖像&#xff08;Source Image&#xff09;中 2. 點擊設置為圖片的原大小&#xff08;Set Native Size&#x…

設計一個會員卡系統

會員卡系統在現代商業環境中是一個重要的客戶關系管理工具。通過會員卡系統&#xff0c;企業可以有效地增加客戶粘性&#xff0c;提高客戶滿意度&#xff0c;進而提升銷售額。本文將詳細討論如何設計一個全面的會員卡系統&#xff0c;包括會員卡的類型、權益設計、續費規則、升…

Java | Leetcode Java題解之第219題存在重復元素II

題目&#xff1a; 題解&#xff1a; class Solution {public boolean containsNearbyDuplicate(int[] nums, int k) {Set<Integer> set new HashSet<Integer>();int length nums.length;for (int i 0; i < length; i) {if (i > k) {set.remove(nums[i - …

# 三 JS的流程控制和函數

三 JS的流程控制和函數 3.1 JS分支結構 if結構 這里的if結構幾乎和JAVA中的一樣,需要注意的是 if()中的非空字符串會被認為是trueif()中的非零數字會被認為是true 代碼 if(false){// 非空字符串 if判斷為trueconsole.log(true) }else{console.log(false) } if(){// 長度為0…

GitHub詳解:代碼托管與協作開發平臺

文章目錄 一、GitHub簡介二、GitHub的核心功能2.1 倉庫&#xff08;Repository&#xff09;2.2 版本控制與分支&#xff08;Branch&#xff09;2.3 Pull Request2.4 Issues與Projects2.5 GitHub Actions 三、GitHub的使用方法3.1 注冊與登錄3.2 創建和管理倉庫3.3 使用Git進行代…

【密碼學】密碼學中的四種攻擊方式和兩種攻擊手段

在密碼學中&#xff0c;攻擊方式通常指的是密碼分析者試圖破解加密信息或繞過安全機制的各種策略。根據密碼分析者對明文、密文以及加密算法的知識程度&#xff0c;攻擊可以分為以下四種基本類型&#xff1a; 一、四種攻擊的定義 &#xff08;1&#xff09;唯密文攻擊(COA, C…

PCIe驅動開發(2)— 第一個簡單驅動編寫和測試

PCIe驅動開發&#xff08;2&#xff09;— 第一個簡單驅動編寫和測試 一、前言 教程參考&#xff1a;02_實戰部分_PCIE設備測試 教程參考&#xff1a;03_PCIe設備驅動源碼解析 二、驅動編寫 新建hello_pcie.c文件 touch hello_pcie.c然后編寫內容如下所示&#xff1a; #i…

【持續集成_03課_Jenkins生成Allure報告及Sonar靜態掃描】

1、 一、構建之后的配置 1、安裝allure插件 安裝好之后&#xff0c;可以在這里搜到已經安裝的 2、配置allure的allure-commandline 正常配置&#xff0c;是要么在工具里配置&#xff0c;要么在系統里配置 allure-commandline是在工具里進行配置 兩種方式進行配置 1&#xff…

原生JavaScript實現錄屏功能

1. 前言 使用JavaScript實現瀏覽器中打開系統錄屏功能 示例圖: 2. 源碼 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><…

LabVIEW機器視覺系統中的圖像畸變、校準和矯正

在機器視覺應用中&#xff0c;圖像畸變、校準和矯正是確保圖像準確性的關鍵步驟。LabVIEW作為一種強大的圖像處理和分析工具&#xff0c;提供了一系列功能來處理這些問題。以下是對圖像畸變、校準和矯正的詳細介紹。 圖像畸變 圖像畸變 是指由于攝像鏡頭的光學特性或拍攝角度問…

算法重新刷題

基礎算法 前綴和 一維前綴和 [USACO16JAN] Subsequences Summing to Sevens S - 洛谷 這一題主要是需要結合數學知識來求解&#xff0c; #include <iostream> #include <cstring> #include <cstdio> #include <algorithm>using namespace std;con…

06pymysql

【一】pymysql 1.我們可以利用pymysql在python中操作數據庫 原理是pyMySQL-->是封裝好的執行subprocess鏈接數據庫執行數據庫命令的模塊 官網&#xff1a;https://zetcode.com/python/pymysql/ 【二】使用示例 import pymysql from pymysql.cursors import DictCursor ?…

進入防火墻Web管理頁面(eNSP USG6000V)和管理員模塊

1、進入防火墻Web管理頁面 USG系列是華為提供的一款高端防火墻產品&#xff0c;其特點在于提供強大的安全防護能力和靈活的擴展性。 以eNSP中的USG6000為例&#xff1a; MGMT口&#xff08;web管理口&#xff09;&#xff1a;對應設備上的G0/0/0口&#xff0c;上面初始配有一…

如何在Spring Boot中實現實時通知

如何在Spring Boot中實現實時通知 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將討論如何在Spring Boot應用中實現實時通知功能&#xff0c;這在現代…

Java的awt和swing的區別

AWT&#xff08;Abstract Window Toolkit&#xff09;和Swing都是Java中用于創建圖形用戶界面&#xff08;GUI&#xff09;的工具包&#xff0c;但它們之間存在一些關鍵的區別。下面我將通過具體的例子來說明這些區別&#xff1a; 1. 跨平臺性能 AWT&#xff1a; AWT是基于本…

實驗六 圖像的傅立葉變換

一&#xff0e;實驗目的 1了解圖像變換的意義和手段&#xff1b; 2熟悉傅立葉變換的基本性質&#xff1b; 3熟練掌握FFT變換方法及應用&#xff1b; 4通過實驗了解二維頻譜的分布特點&#xff1b; 5通過本實驗掌握利用MATLAB編程實現數字圖像的傅立葉變換。 6評價人眼對圖…

LeetCode 每日一題 2024/7/1-2024/7/7

記錄了初步解題思路 以及本地實現代碼&#xff1b;并不一定為最優 也希望大家能一起探討 一起進步 目錄 7/1 2065. 最大化一張圖中的路徑價值7/2 3115. 質數的最大距離7/3 3099. 哈沙德數7/4 3086. 拾起 K 個 1 需要的最少行動次數7/5 3033. 修改矩陣7/6 3101. 交替子數組計數7…