在正则表达式中捕获组和模式拆分方法

时间:2018-03-10 19:32:25

标签: java regex split capturing-group

我如何理解以下代码的输出?代码的前四个打印语句是关于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);
            }

        }
    }

结果

enter image description here

Edit-1

查询

  • 如果我谈论捕获群组,我无法弄清楚'\ 1'或'\ 2'在这里有什么用?这些如何评估为真或假。
  • 如果我谈论模式分割方法,我想知道字符串分割是如何发生的。这种拆分方法与普通字符串拆分方法的工作方式有何不同?

2 个答案:

答案 0 :(得分: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()方法,该方法始终返回布尔值(true或false)。此方法主要用于一种或另一种的字符串验证。取第一个和第二个示例正则表达式,它们都是:"(\\w\\d)\\1",然后通过匹配()来处理该表达式对两个提供的字符串("a2a2""a2b2") strong>方法,他们肯定会按顺序返回布尔 true false

这里的真正关键是知道特定Regular Expression要验证的 。上面的表达式仅适用于1个捕获组,用括号表示。 \\ w 用于匹配任何单个 字符 ,等于 az AZ 0-9 _ (下划线字符)。 \\ d 用于匹配单个数字,该数字等于 0 9 中的任何数字。

  

注意:实际上,表达元字符写为 \ w \ d ,但因为Java字符串中的转义字符( \ )需要转义,您必须添加额外的转义符   字符。

\ 1 用于查看与第一个捕获组最近匹配的文本是否存在单个匹配项。由于只指定了一个捕获组,因此此处只能使用值1。嗯,这并不完全正确,你可以在这里使用 0 的值但是你不在任何捕获组中寻找匹配,这消除了这里的目的。任何其他大于 1 的值都会创建表达式异常,因为您只有1个捕获组。

底线,表达式查看提供的字符串中的前两个字符:

  • 提供的字符串中的第一个字符( \\ w )是大写还是小写 A到Z _ 0到9 中的数字?如果不是,那么就没有匹配,并且返回布尔 false 但是,如果有,那么......
  • 提供的字符串中的第二个字符( \\ d )是否为数字 从 0到9 ?如果不是,则返回布尔 false 但是,如果有则....
  • 剩余的2个字符是否完全相同(包括字母 如果使用 a-z A-Z ,则为case。如果剩下的2个字符不是 相同或者剩余的两个以上的字符然后是布尔值 返回 false 。但是,如果剩下的两个字符相同,则返回布尔 true

基本上,表达式仅用于验证提供的字符串中的 Last Two 字符是否匹配 前两个 < / strong>提供的字符串相同的字符。这就是第二个控制台打印的原因:

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

返回布尔 false b2 a2相同,而在第一个控制台中打印:

System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true
最后两个 字符a2确实匹配 前两个 字符{{1因此返回布尔 true

现在您将注意到在另外两个控制台打印中:

a2

使用的正则表达式包含 2 捕获组(两组括号)。这里适用相同类型的匹配,但是针对两个捕获组,而不是像前两个控制台打印一样。

如果您想了解这些正则表达式如何发挥作用并获得表达式含义的解释,请在regex101.com使用正则表达式测试程序。这也是一个很好的Regular Expressions资源。

  

<强> Pattern.split():

在这种情况下,使用 Pattern.split()方法在我看来有点矫枉过正,因为 String.split()接受正则表达式但确实有它在其他领域的目的。从来没有它是如何使用它的一个很好的例子。这里使用 .split()方法来执行基于提供给它的字符串的分组以及通过模式被视为正则表达式的分组,在这种情况下是&# 34; \\ W&#34; (否则: \ W )。 \ W (大写 W )表示匹配任何非单词字符不等于 az AZ 0-9 _ 。此表达式基本上与&#34; \ w&#34; (小写 w )相反。提供的字符串中包含 @ $ 字符(是的...逗号) ,分号,感叹号等):

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

被认为是非单词字符,因此在其中任何一个上执行拆分,从而产生包含以下内容的字符串数组:

"one@two#three:four$five"

使用 String.split()方法可以完成同样的事情,因为tis方法允许应用正则表达式:

[one, two, three, four, five]

甚至:

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

甚至:

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

或一直打开......

是的... &#34; \\ W&#34; 更容易,因为它涵盖了所有非单词字符。的;)

答案 1 :(得分:0)

  

如果我谈论捕获群组,我无法弄清楚'\ 1'或'\ 2'的用法在这里?这些如何评估是真还是假。

答案:

  • \\1重复第一个捕获的组(即a2捕获的(\\w\\d)
  • \\2重复第二个捕获的组(即B2捕获的(B\\d)

这些组合的实际名称是 backreferences

  

与捕获匹配的输入字符串部分   组(s)保存在内存中,以便以后通过反向引用进行调用。一个   反向引用在正则表达式中指定为反斜杠   ()后跟一个数字,表示该组的编号   召回。

  

如果我谈论Pattern split方法,我想知道字符串拆分是如何发生的。这种拆分方法与普通字符串拆分方法的工作方式有何不同?

Answer

  

Pattern类中的split()方法可以使用正则表达式(模式)作为分隔符将文本拆分为String数组

不是使用修复字符串或字符显式拆分字符串,而是在这里提供一个强大且有弹性的正则表达式。