最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java正則表達(dá)式學(xué)習(xí)之分組與替換

 更新時(shí)間:2020年09月02日 11:26:07   作者:jiaobuchong  
這篇文章主要給大家介紹了關(guān)于Java正則表達(dá)式學(xué)習(xí)之分組與替換的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

正則表達(dá)式的子表達(dá)式(分組)不是很好懂,但卻是很強(qiáng)大的文本處理工具。

1 正則表達(dá)式熱身

匹配電話號(hào)碼

// 電話號(hào)碼匹配
// 手機(jī)號(hào)段只有 13xxx 15xxx 18xxxx 17xxx
System.out.println("18304072984".matches("1[3578]\\d{9}")); // true

// 座機(jī)號(hào):010-65784236,0316-3312617,022-12465647,03123312336
String regex = "0\\d{2}-?\\d{8}|0\\d{3}-?\\d{7}";
String telStr = "010-43367458";
System.out.println(telStr.matches(regex)); // true

匹配郵箱

String mail = "i@jiaobuchong.com.cn";
String reg = "[a-zA-Z_0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,2}";
System.out.println(mail.matches(reg)); // true

特殊字符替換

將不是中文的字符替換為空:

String input = "神探狄仁&*%$杰之四大天王@bdfbdbdfdgds23532";
String reg = "[^\\u4e00-\\u9fa5]";
input = input.replaceAll(reg, "");
System.out.println(input); // 神探狄仁杰之四大天王

漢字的Unicode編碼范圍是:\u4e00-\u9fa5

2 分組

組是用括號(hào)劃分的正則表達(dá)式,可以根據(jù)組的編號(hào)來引用某個(gè)組。組號(hào)為 0 表示整個(gè)表達(dá)式,組號(hào) 1 表示第一對(duì)括號(hào)擴(kuò)起的組,以此類推。

看 Java API 中 Pattern 中的描述:

Capturing groups are numbered by counting their opening parentheses from left to right. In the expression ((A)(B(C))), for example, there are four such groups:

1. ((A)(B(C)))
2. (A)
3. (B(C))
4. (C)

再比如 A(B(C))D 有三個(gè)組:組 0 是 ABCD,組 1 是 BC,組 2 是 C,

可以根據(jù)有多少個(gè)左括號(hào)來來確定有多少個(gè)分組,括號(hào)里的表達(dá)式都稱子表達(dá)式。

Eg1:

Matcher 對(duì)象提供很多方法:

  1. goupCount() 返回該正則表達(dá)式模式中的分組數(shù)目,對(duì)應(yīng)于「左括號(hào)」的數(shù)目
  2. group(int i) 返回對(duì)應(yīng)組的匹配字符,沒有匹配到則返回 null
  3. start(int group) 返回對(duì)應(yīng)組的匹配字符的起始索引
  4. end(int group) 返回對(duì)應(yīng)組的匹配字符的最后一個(gè)字符索引加一的值
// 這個(gè)正則表達(dá)式有兩個(gè)組,
// group(0) 是 \\$\\{([^{}]+?)\\}
// group(1) 是 ([^{}]+?)
String regex = "\\$\\{([^{}]+?)\\}";
Pattern pattern = Pattern.compile(regex);
String input = "${name}-babalala-${age}-${address}";

Matcher matcher = pattern.matcher(input);
System.out.println(matcher.groupCount());
// find() 像迭代器那樣向前遍歷輸入字符串
while (matcher.find()) {
 System.out.println(matcher.group(0) + ", pos: "
 + matcher.start() + "-" + (matcher.end() - 1));
 System.out.println(matcher.group(1) + ", pos: " +
 matcher.start(1) + "-" + (matcher.end(1) - 1));
}

輸出:

1
${name}, pos: 0-6
name, pos: 2-5
${age}, pos: 17-22
age, pos: 19-21
${address}, pos: 24-33
address, pos: 26-32

group,翻譯成中文就是分組。

group()或group(0)對(duì)應(yīng)于整個(gè)正則表達(dá)式每次匹配到的內(nèi)容,

group(1)表示括號(hào)中(一個(gè)子表達(dá)式分組)匹配到的內(nèi)容。

Eg2:

為了更直觀的看分組,在 Eg1 的正則表達(dá)式上再多加一對(duì)括號(hào):

String regex = "(\\$\\{([^{}]+?)\\})";
Pattern pattern = Pattern.compile(regex);
String input = "${name}-babalala-${age}-${address}";

Matcher matcher = pattern.matcher(input);
// matcher.find() 方法會(huì)對(duì) input 這個(gè)字符串多次進(jìn)行匹配,如果能匹配到,這個(gè)匹配結(jié)果里就會(huì)包含多個(gè)分組,我們可以從分組里提取我們想要的結(jié)果
while (matcher.find()) {
 System.out.println(matcher.group(0) + ", pos: " + matcher.start());
 System.out.println(matcher.group(1) + ", pos: " + matcher.start(1));
 System.out.println(matcher.group(2) + ", pos: " + matcher.start(2));
}

輸出:

${name}, pos: 0
${name}, pos: 0
name, pos: 2
${age}, pos: 17
${age}, pos: 17
age, pos: 19
${address}, pos: 24
${address}, pos: 24
address, pos: 26

由此可得出一對(duì)括號(hào)一個(gè)分組,可以通過左括號(hào)數(shù)來確定有多少個(gè)分組。

通過group()獲取分組中的匹配字串應(yīng)用場(chǎng)景很廣泛,

在筆者的一個(gè)項(xiàng)目中,通過使用這個(gè)特性實(shí)現(xiàn)了很有意思的通配符替換,感動(dòng)!

Eg3(通過分組提取想要的數(shù)據(jù)):

 // 這個(gè)正則表達(dá)式會(huì)提取字符串中的「數(shù)字」和「字母」
 Pattern pattern = Pattern.compile("([0-9]+).*?([a-zA-Z]+)");
 String input = "那就20200719這樣吧sunny。。。。。。。122432該拿什么與眼淚抗衡twinkle";
 Matcher matcher = pattern.matcher(input);
 // 每個(gè)匹配到的子串分組的個(gè)數(shù)
 int group = matcher.groupCount();
 // 如果輸入串有多個(gè)可被匹配的子串,這里會(huì)多次進(jìn)行匹配
 while (matcher.find()) {
 System.out.println("匹配到的子串:" + matcher.group()); // 匹配到的子串
 for (int i = 1; i <= group; i++) {
 System.out.println("分組" + i + ": " + matcher.group(i));
 }
 }

輸出:

匹配到的子串:20200719這樣吧sunny
分組1: 20200719
分組2: sunny
匹配到的子串:122432該拿什么與眼淚抗衡twinkle
分組1: 122432
分組2: twinkle

3 分組替換

Eg1:

String tel = "18304072984";
// 括號(hào)表示組,被替換的部分$n表示第n組的內(nèi)容
tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
System.out.print(tel); // output: 183****2984

replaceAll 是一個(gè)替換字符串的方法,正則表達(dá)式中括號(hào)表示一個(gè)分組,replaceAll 的參數(shù) 2 中可以使用 $n(n 為數(shù)字)來依次引用子表達(dá)式中匹配到的分組字串,"(\\d{3})\\d{4}(\\d{4})", "$1****$2",分為前(前三個(gè)數(shù)字)中間四個(gè)數(shù)字(最后四個(gè)數(shù)字) 替換為(第一組數(shù)字保持不變 $1)(中間為 * )(第二組數(shù)字保持不變 $2)。

String one = "hello girl hi hot".replaceFirst("(\\w+)\\s+(\\w+)", "$2 $1"); 
String two = "hello girl hi hot".replaceAll("(\\w+)\\s+(\\w+)", "$2 $1"); 
System.out.println(one); // girl hello hi hot
System.out.println(two); // girl hello hot hi

理解了Eg1,這個(gè)例子也自然就理解了。

Eg3:

來一個(gè)實(shí)用的例子,重復(fù)標(biāo)點(diǎn)符號(hào)替換:

String input = "假如生活欺騙了你,,,相信吧,,,快樂的日子將會(huì)來臨!??!…………";

// 重復(fù)標(biāo)點(diǎn)符號(hào)替換
String duplicateSymbolReg = "([。?!?!,]|\\.\\.\\.|……)+";
input = input.replaceAll(duplicateSymbolReg, "$1");
System.out.println(input);

輸出:

假如生活欺騙了你,相信吧,快樂的日子將會(huì)來臨!……

正則表達(dá)式:([。?!?!,]|\\.\\.\\.|……)+,括號(hào)中是一個(gè)分組:表示一個(gè)標(biāo)點(diǎn)符號(hào),+表示這個(gè)分組出現(xiàn)一次或多次,$1分組的內(nèi)容(一個(gè)標(biāo)點(diǎn)符號(hào))。replaceAll 就使用$1去對(duì)字符串進(jìn)行替換了。

Eg4:

IP地址排序

String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
ip = ip.replaceAll("(\\d+)", "00$1");
System.out.println(ip);

ip = ip.replaceAll("0*(\\d{3})", "$1");
System.out.println(ip);
String[] strs = ip.split(" ");

Arrays.sort(strs);
for (String str : strs) {
 str = str.replaceAll("0*(\\d+)", "$1");
 System.out.println(str);
}

輸出:

00192.0068.001.00254 00102.0049.0023.00013 0010.0010.0010.0010 002.002.002.002 008.00109.0090.0030
192.068.001.254 102.049.023.013 010.010.010.010 002.002.002.002 008.109.090.030
2.2.2.2
8.109.90.30
10.10.10.10
102.49.23.13
192.68.1.254

  1. 讓IP地址的每一段都是3位,替換之后有4位的情況
  2. 保證IP地址每一段都是3位
  3. 排序之

寫到這里,筆者不禁感嘆,真的很強(qiáng)大!

4 反向引用

使用小括號(hào)指定一個(gè)子表達(dá)式分組后,匹配這個(gè)子表達(dá)式的文本可以在表達(dá)式或其它程序中作進(jìn)一步的處理。默認(rèn)情況下,每個(gè)分組會(huì)自動(dòng)擁有一個(gè)組號(hào),規(guī)則是:以分組的左括號(hào)為標(biāo)志,從左向右,第一個(gè)分組的組號(hào)為1,第二個(gè)為2,以此類推。

Eg:

/* 這個(gè)正則表達(dá)式表示 安安靜靜 這樣的疊詞 */
String regex = "(.)\\1(.)\\2"; 
System.out.println("安安靜靜".matches(regex)); // true
System.out.println("安靜安靜".matches(regex)); // false

上面 (.) 表示一個(gè)分組,里面 . 表示任意字符,每一個(gè)字符都是一個(gè)分組,
\\1表示組1(安)又出現(xiàn)了一次,\\2表示組2(靜)又出現(xiàn)了一次。

那匹配 安靜安靜,怎么寫正則表達(dá)式?根據(jù)上面的例子,將安靜分成一個(gè)組,然后這個(gè)組又出現(xiàn)了一次就是安靜安靜:

String regex = "(..)\\1"; 
System.out.println("安靜安靜".matches(regex)); // true
System.out.println("安安靜靜".matches(regex)); // false

5 反向引用替換

Eg1:

String str = "我我...我我...我要..要要...要要...找找找一個(gè)....女女女女...朋朋朋朋朋朋...友友友友友..友.友...友...友友!?。?;
 
/*將 . 去掉*/
str = str.replaceAll("\\.+", "");
System.out.println(str);

str = str.replaceAll("(.)\\1+", "$1");
System.out.println(str);

輸出:

我我我我我要要要要要找找找一個(gè)女女女女朋朋朋朋朋朋友友友友友友友友友友?。。?br /> 我要找一個(gè)女朋友!

(.)表示任意一個(gè)字符都會(huì)成為一個(gè)分組;\\1+ 引用分組(一個(gè)字符),表示出現(xiàn)1次或多次這個(gè)分組。 $1引用分組(.)將多個(gè)重復(fù)字符替換成一個(gè)字符。

Eg2:

替換重復(fù)出現(xiàn)的兩位數(shù)之間的內(nèi)容:

"xx12abdd12345".replaceAll("(\\d{2}).+?\\1", ""); //結(jié)果為 xx345

是不是覺得很神奇!

使用replace系列的方法要注意的一個(gè)異常: Java replaceAll()方法報(bào)錯(cuò)Illegal group reference

參考:

到此這篇關(guān)于Java正則表達(dá)式學(xué)習(xí)之分組與替換的文章就介紹到這了,更多相關(guān)Java正則表達(dá)式分組與替換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中為什么要實(shí)現(xiàn)Serializable序列化

    Java中為什么要實(shí)現(xiàn)Serializable序列化

    在Java編程中,Serializable序列化是一個(gè)常見的概念,它允許對(duì)象在網(wǎng)絡(luò)上傳輸或持久化到磁盤上,本文將深入探討為什么在Java中要實(shí)現(xiàn)Serializable序列化,并通過示例代碼來解釋其重要性
    2023-10-10
  • JSON Web Token在登陸中的使用過程

    JSON Web Token在登陸中的使用過程

    這篇文章主要介紹了JSON Web Token在登陸中的使用過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • java.security.egd?作用詳解

    java.security.egd?作用詳解

    這篇文章主要為大家介紹了java.security.egd作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Mybatis-Plus查詢中如何排除標(biāo)識(shí)字段

    Mybatis-Plus查詢中如何排除標(biāo)識(shí)字段

    這篇文章主要介紹了Mybatis-Plus查詢中排除標(biāo)識(shí)字段的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java current并發(fā)包超詳細(xì)分析

    Java current并發(fā)包超詳細(xì)分析

    current并發(fā)包、在JDK1.5之前Java并沒有提供線程安全的一些工具類去操作多線程,需要開發(fā)人員自行編寫實(shí)現(xiàn)線程安全,但仍然無法完全避免低性能、死鎖、資源管理等問題。在JDK1.5時(shí)新增了java.util.current并發(fā)包,其中提供了許多供我們使用的并發(fā)編程工具類
    2023-02-02
  • 完美解決因數(shù)據(jù)庫一次查詢數(shù)據(jù)量過大導(dǎo)致的內(nèi)存溢出問題

    完美解決因數(shù)據(jù)庫一次查詢數(shù)據(jù)量過大導(dǎo)致的內(nèi)存溢出問題

    今天小編就為大家分享一篇完美解決因數(shù)據(jù)庫一次查詢數(shù)據(jù)量過大導(dǎo)致的內(nèi)存溢出問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • SpringBoot3整合Druid監(jiān)控功能的項(xiàng)目實(shí)踐

    SpringBoot3整合Druid監(jiān)控功能的項(xiàng)目實(shí)踐

    Druid連接池作為一款強(qiáng)大的數(shù)據(jù)庫連接池,提供了豐富的監(jiān)控和管理功能,成為很多Java項(xiàng)目的首選,本文主要介紹了SpringBoot3整合Druid監(jiān)控功能的項(xiàng)目實(shí)踐,感興趣的可以了解一下
    2024-01-01
  • MyBatis中的SQL映射文件如何配置參數(shù)映射和使用方法

    MyBatis中的SQL映射文件如何配置參數(shù)映射和使用方法

    MyBatis 是一種開源的 Java 持久化框架,它可以自動(dòng)將數(shù)據(jù)庫中的數(shù)據(jù)映射到 Java 對(duì)象中,并且使得 Java 對(duì)象可以非常方便地存儲(chǔ)到數(shù)據(jù)庫中,本文將介紹 MyBatis 中 SQL 映射文件的參數(shù)映射配置和使用方法,需要的朋友可以參考下
    2023-07-07
  • Spring Cloud Gateway 使用JWT工具類做用戶登錄校驗(yàn)功能

    Spring Cloud Gateway 使用JWT工具類做用戶登錄校驗(yàn)功能

    這篇文章主要介紹了Spring Cloud Gateway 使用JWT工具類做用戶登錄校驗(yàn)的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • 分布式鎖redisson實(shí)現(xiàn)原理源碼詳解

    分布式鎖redisson實(shí)現(xiàn)原理源碼詳解

    這篇文章主要介紹了源碼詳解分布式鎖redisson實(shí)現(xiàn)原理,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05

最新評(píng)論

仙桃市| 垦利县| 敦煌市| 正安县| 麟游县| 萝北县| 嵊泗县| 南开区| 昂仁县| 西安市| 金溪县| 亳州市| 开平市| 柘城县| 耿马| 叙永县| 耿马| 洛浦县| 夏邑县| 会同县| 衡阳县| 崇明县| 富源县| 天全县| 商丘市| 柳林县| 临沂市| 梁山县| 温州市| 林芝县| 太白县| 徐闻县| 运城市| 修水县| 灵丘县| 崇州市| 临海市| 仙桃市| 宜宾县| 乳源| 丰宁|