簡體   English   中英

正則表達式中的捕獲組和模式拆分方法

[英]Capturing groups and Pattern split method in regular expression

我如何理解以下代碼的輸出? 代碼的前四個打印語句是關於 Java 中正則表達式中的捕獲組,其余代碼是關於Pattern split方法。 我參考了一些文檔來感知代碼的輸出(如圖所示),但無法弄清楚它是如何工作並顯示此輸出的。

Java代碼

    import java.util.*;
    import java.util.regex.*;
    import java.lang.*;
    import java.io.*;

    /* Name of the class has to be "Main" only if the class is public. */
    public class Codechef
    {
        public static void main(String[] args) {
            //Capturing Group in Regular Expression
            System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true
            System.out.println(Pattern.matches("(\\w\\d)\\1", "a2b2")); //false
            System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B2AB")); //true
            System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B3AB")); //false
            // using pattern split method
            Pattern pattern = Pattern.compile("\\W");
            String[] words = pattern.split("one@two#three:four$five");
            System.out.println(words);
            for (String s : words) {
                System.out.println("Split using Pattern.split(): " + s);
            }

        }
    }

結果

在此處輸入圖片說明

編輯-1

查詢

  • 如果我談論捕獲組,我無法弄清楚這里的 '\\1' 或 '\\2' 有什么用? 這些如何評估為真或假。
  • 如果我談論模式拆分方法,我想知道字符串拆分是如何發生的。 這種拆分方法與普通字符串拆分方法的工作方式有何不同?

第一個控制台打印行...

System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2b2")); //false
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B2AB")); //true
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B3AB")); //false

利用matches()方法,它總是返回一個布爾值(真或假)。 此方法主要用於一種或另一種字符串驗證。 以第一個和第二個正則表達式示例為例,它們都是: "(\\\\w\\\\d)\\\\1"然后通過matches()方法針對兩個提供的字符串( "a2a2""a2b2" )處理該表達式正如他們所做的那樣,您肯定會按順序返回布爾值truefalse

這里真正的關鍵是知道什么特定的正則表達式是假設進行驗證。 上面的表達式僅適用於括號中表示的 1 個捕獲組。 \\\\w用於匹配任何等於azAZ0-9_ (下划線字符)的單個單詞字符 \\\\d用於匹配單個數字,等於09 之間的任何數字。

注意:實際上,表達式Meta 字符寫為\\w\\d,但由於 Java 字符串中的轉義字符 ( \\ ) 需要轉義,因此您必須添加額外的轉義字符。

\\1用於查看是否存在與第一個捕獲組最近匹配的相同文本的單個匹配項。 由於只指定了一個捕獲組,因此此處只能使用值 1。 嗯,這並不完全正確,您可以在此處使用0值,但是您不會在任何捕獲組中尋找匹配項,這消除了此處的目的。 任何其他大於1 的值都會創建表達式異常,因為您只有 1 個捕獲組。

底線,表達式查看所提供字符串中的前兩個字符:

  • 所提供字符串中的第一個字符 ( \\\\w ) 是大寫還是小寫A 到 Z_0 到 9 之間的數字 如果不是,則沒有匹配項,並且返回布爾值false ,但是,如果存在.....
  • 提供的字符串中的第二個字符 ( \\\\d ) 是0 到 9 之間的數字嗎? 如果不是,則返回布爾值,但是,如果有則......
  • 其余 2 個字符是否完全相同(如果使用azAZ,則包括字母大小寫)。 如果剩余的 2 個字符不相同或剩余的字符多於兩個,則返回布爾值false 但是,如果剩下的兩個字符相同,則返回 boolean true

基本上,表達僅用於驗證所提供的字符串內的最后兩個字符匹配相同提供的字符串的前兩個字符。 這就是第二個控制台打印的原因:

System.out.println(Pattern.matches("(\\w\\d)\\1", "a2b2")); //false

返回一個布爾值false, b2一樣的a2 ,而在第一個控制台打印:

System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true

最后兩個字符a2確實與前兩個字符a2匹配,因此返回布爾值true

您現在會注意到在其他兩個控制台打印中:

System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B2AB")); //true
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B3AB")); //false

使用的正則表達式包含2 個捕獲組(兩組括號)。 相同類型的匹配在這里適用,但針對兩個捕獲組,而不是像前兩個控制台打印那樣的一個。

如果您想了解這些正則表達式如何發揮作用並獲得有關表達式含義的解釋,請使用regex101.com 上的正則表達式測試 這也是一個很好的正則表達式資源。

Pattern.split():

在這種情況下,在我看來,使用Pattern.split()方法有點矯枉過正,因為String.split()接受正則表達式,但在其他領域確實有它的用途。 無論如何,它是如何使用它的一個很好的例子。 .split()方法在此處用於根據提供給它的 String 以及通過 Pattern 被視為正則表達式的內容執行分組,在這種情況下為“\\\\W” (否則為: \\W )。 \\W (大寫W )表示“匹配任何不等於azAZ0-9_ 的非單詞字符。 這個表達式基本上與“\\w”相反(帶有小寫的w )。 提供的字符串中包含的字符@#:$ (是的...逗號、分號、感嘆號等):

"one@two#three:four$five"

被認為是非單詞字符,因此對它們中的任何一個進行拆分,從而產生一個包含以下內容的字符串數組:

[one, two, three, four, five]

使用String.split()方法可以通過這種方式完成同樣的事情,因為 tis 方法允許應用正則表達式:

String[] s = "one@two#three;four$five".split("\\W");

甚至:

String[] s = "one@two#three;four$five".split("[@#:$]");

甚至:

String[] s = "one@two#three;four$five".split("@|#|:|\\$");
// The $ character is a reserved RegEx symbol and therefore
// needs to be escaped.

或者………………

是的...... “\\\\W”更容易,因為它涵蓋了所有非單詞字符。 ;)

如果我談論捕獲組,我無法弄清楚這里 '\\1' 或 '\\2' 的用法是什么? 這些如何評估為真或假。

回答:

  • \\\\1重復第一個捕獲的組(即a2捕獲的(\\\\w\\\\d)
  • \\\\2重復第二個捕獲的組(即B2捕獲的(B\\\\d)

這些組合的實際名稱是反向引用

與捕獲組匹配的輸入字符串部分保存在內存中,以便以后通過反向引用調用。 反向引用在正則表達式中指定為反斜杠 () 后跟一個數字,表示要調用的組的編號。


如果我談論模式拆分方法,我想知道字符串拆分是如何發生的。 這種拆分方法與普通字符串拆分方法的工作方式有何不同?

回答

Pattern 類中的 split() 方法可以將文本拆分為字符串數組,使用正則表達式(模式)作為分隔符

與使用修復字符串或字符顯式拆分字符串不同,這里您提供了一個更強大和更有彈性的正則表達式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM