日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java中的正则表达式捕获组与引用的概念

發布時間:2024/9/30 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中的正则表达式捕获组与引用的概念 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天群里有個人問,怎樣用增則表達式匹配三角形的三邊,其實只是要匹配三個數字而已,如 301 402 503 開始認為很簡單,我就寫了一個 ??"(([1-9]\\d?)\\s){2}$2" 結果他說錯了,我感覺很奇怪,于是自己打開電腦試了試,果然是錯的,然后看了看以前的筆記,發現我的Back 引用捕獲組錯了,因為$符號是在不同字符串中對捕獲組的引用看下面這個方法

public static void text_1(){String str="我。。我要。。。要要要。。學。。學。編。。。程";str=str.replaceAll("\\。+","");System.out.println(str);<span style="background-color: rgb(255, 255, 153);">str=str.replaceAll("(.)\\1*","$1");</span>System.out.println(str);}這句話的意思是將$1調用(.)匹配到的結果,注意是匹配到的結果,也就是()括號里匹配到什么就被調用什么,這也是本人為什么要寫這篇博客的原因所在。

? 可能大家還沒有理解我的意思,下面跟著我來理解

? 上面說的$是在不同字符串中的引用捕獲組,我一直強調的是引用的是結果,看下面這個代碼:

public void test(){<span style="color:#3333ff;">String regex="(([1-9]\\d?)\\s){2}\2";</span>String str="3 4 5";System.out.println(str.matches(regex));}
上面這段代碼是我一直想不懂最后的結果為什么是false, String regex="(([1-9]\\d?)\\s){2}\2"; ? ? ? ??

我們來分析這句話:([1-9]\\d?) ?這句的意思是匹配一個正整數,如3,401,等 ? 。([1-9]\\d?)\\s這句話是匹配一個數之后空格隔開,(([1-9]\\d?)\\s){2}正好出現兩次也就是如:3 4 ,最后\2是調用角標為2的捕獲組,也就是([1-9]\\d?) ,自己一直在思考為什么是錯的,知道看到一篇博文才恍然大悟,引用捕獲組的不是捕獲組里面的表達式,而是引用捕獲組所捕獲到的具體內容,拿上面的例子來說:當第一次匹配時,([1-9]\\d?) 此匹配組所捕獲的是3這個具體的字符串,所以你下次引用時就必須為3這個字符串,而不是再次調用([1-9]\\d?) 這個正則表達式這么簡單,這就是我以前最大的誤區,所以,自己也是花了很多時間才發現,改正上面的代碼:

public static void test(){<span style="color:#000099;">String regex="([1-9]\\d*\\s){2}[1-9]\\d*";</span>String str="304 4 5";System.out.println(str.matches(regex));}歸根結底是我將{n}出現次數和\n引用捕獲組搞混淆了,希望大家不要記錯了!!!下面是我為大家扒過來的我覺得比較好的博文,這里我只是強調捕獲組引用的概念,其他關于正則表達式不做過多的介紹,(現在已經深夜1.30了,哎,苦逼的程序員人生啊,該睡了)看下面代碼:


Regex :

  • 本文主要講述正則表達式中的捕獲組(Capturing Group)的概念
  • 本文的正則表達式在 Java 中測試(需要注意的是這里的部分正則表達式在?Java7?中才能應用,下面會注明)
  • 本文正則表達式用???????????高亮標出

Capturing Group : (X)

簡單的理解就是把正則表達式中的某部分用 () 括起來表示為一個組,純理論解釋不怎么好解釋,詳細還看下面的舉例。

??????? 舉例:

  • (Ggi)cci?與Ggicci?都匹配 "Ggicci",只不過前面把 Ggi 作為一個捕獲組,在匹配到的同時它可以捕獲 "Ggi" 這樣的字符串供逆向引用(Back Reference)見下一欄。
  • Ggicci*?與(Ggicci)*?不同在于Ggicci*?匹配的是 "Ggicci" 和 "Ggicci…i" 這種情況,而(Ggicci)*?匹配的是 "Ggicci" 和 "GgicciGgicci…Ggicci" 這種情況。

Back Reference :

逆向引用指的是正則表達式中某個捕獲組捕獲到的字符串供正則表達式構建其自身匹配規則的方式。這是我自己歸納的理論,聽起來肯定很晦澀,詳細見下面講解

????????捕獲組的編號與命名:

??????? 如?((A)(B(C)))?“摘自Java7 Doc”,這里有 4 個組:

  • 編號捕獲組
    1((A)(B(C)))
    2(A)
    3(B(C))
    4(C)

            ??????? 在未對捕獲組人為命名的時候,對捕獲組的編號是默認的從左到右依次萃取 (?和與之對應成一對的 )。如上,一共 4 個 ( ,所以有 4 個組,按 ( 的出現次序編號。

            • (?<name>X)?命名捕獲組為 name,在?Java7?中; 1: String source = "Ggicci was born in 1991 and is 20 years old now. He weights 54kg and is 170cm tall."; 2: Pattern pattern = Pattern.compile("(?<user>[Gg]gicci)|(?<digital>\\d+)"); 3: Matcher matcher = pattern.matcher(source); 4: while (matcher.find()) { 5: System.out.println(matcher.group()); 6: } 代碼中的正則表達式(已加粗)匹配 Ggicci 或 ggicci 或一段數字,輸出為: 1: //輸出: 2: Ggicci 3: 1991 4: 20 5: 54 6: 170 (?<user>[Gg]gicci)?把捕獲組命名為 user,我們用 Matcher 類的 group(String name) 方法,即 matcher.group("user"); 可以獲取該捕獲組捕獲的內容,其它的捕獲組內容將為 null: 1: System.out.println(matcher.group("user")); //替換上面 while 循環中的輸出語句 2: //輸出: 3: Ggicci 4: null 5: null 6: null 7: null 當然用 Matcher 類的 group(int group) 方法也可以,這里 user 捕獲組的默認編號為 1,所以 matcher.group(1) 同 matcher.group("user") 一樣。(?<digital>\d+)?也同樣去理解。
            • (?:X)?取消捕獲組命名,注意這種方式連捕獲組默認的編號也會取消,所以在調用 Matcher.group(int) 或 Matcher.group(String) 的時候會異常;

            • \n?表示引用第 n 個捕獲組捕獲到的內容; 1: String source = "Hello, my my name is uh.. is is Gg.. ggicci ggicci ggicci ggicci"; 2: Pattern pattern = Pattern.compile("\\b(\\w+)\\b((\\s+)\\1\\b)+"); 3: Matcher matcher = pattern.matcher(source); 4: while (matcher.find()) { 5: System.out.println(matcher.group()); 6: } 這段正則表達式?\b(\w)\b((\s+)\1)+?匹配字符串重復的以空格符間隔的單詞。其中?\1?引用了捕獲組?(\w)?匹配到的內容。比如 (\w) 第一次匹配了 "Hello",\1 引用了 "Hello" 后正則表達式其實已經變成了\bHello\b((\s+)Hello)+?了(這是從形式上去理解,具體內部機制如何,親,我目前真的不知道 : )),但是顯然后面沒有 "Hello" 可以匹配了,(\w) 第二次匹配了 "my",\1 引用了 "my",找到匹配,然后依次下去,輸出如下: 1: //輸出: 2: my my 3: is is 4: ggicci ggicci ggicci ggicci
            • \k<name>?表示引用命名為 name 的捕獲組捕獲到的內容,在Java7?中; 1: //這里同上面的正則表達式一樣,只不過給 \1 取了個名字叫 repeat 2: //然后用 \k<repeat> 代替 \1 而已 3: Pattern pattern = Pattern.compile("\\b(?<repeat>\\w+)\\b((\\s+)\\k<repeat>\\b)+");




            總結

            以上是生活随笔為你收集整理的java中的正则表达式捕获组与引用的概念的全部內容,希望文章能夠幫你解決所遇到的問題。

            如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。