Java 正则表达式



  • 正则表达式

    正则表达式用于定义可用于搜索,操作和编辑文本的字符串模式。 这些表达式也称为Regex(正则表达式的缩写)。
    让我们举个例子来更好地理解它:
    在下面的示例中,正则表达式.*book.*用于搜索文本中字符串"book"的出现。
    import java.util.regex.*;  
    class RegexExample1{  
       public static void main(String args[]){  
          String content = "This is Chaitanya " +
                "from Beginnersbook.com.";
    
          String pattern = ".*book.*";
    
          boolean isMatch = Pattern.matches(pattern, content);
          System.out.println("The text contains 'book'? " + isMatch);
       }
    }
    
    在本教程中,我们将学习如何定义模式以及如何使用它们。 java.util.regex API(在处理正则时需要导入的包)有两个主要类:
    • 1)java.util.regex.Pattern –用于定义模式
    • 2)java.util.regex.Matcher –用于使用模式对文本执行匹配操作
  • java.util.regex.Pattern 类

    1) Pattern.matches() 方法
    在上面的示例中,我们已经在给定文本中搜索字符串"book"的过程中看到了此方法的用法。 这是使用正则表达式在文本中搜索字符串的最简单,最简单的方法之一。
    String content = "This is a tutorial Website!";
    String patternString = ".*tutorial.*";
    boolean isMatch = Pattern.matches(patternString, content);
    System.out.println("The text contains 'tutorial'? " + isMatch);
    
    如您所见,我们使用了Pattern类的matchs()方法来搜索给定文本中的模式。 模式.*tutorial.*在字符串"tutorial"的开头和结尾允许零个或多个字符(表达式".*"用于表示零个或多个字符)。
    局限性:通过这种方式,我们可以搜索文本中单个模式的出现。 为了匹配多次出现,您应该使用Pattern.compile()方法(在下一节中讨论)。
    2) Pattern.compile() 方法
    在上面的示例中,我们在文本中搜索了一个字符串"tutorial",即区分大小写,但是,如果您要进行大小写不敏感搜索或要搜索多个匹配项,则可能需要先使用Pattern.compile(),然后在文本中进行搜索。 这就是这种方法可以用于这种情况的方式。
    String content = "This is a tutorial Website!";
    String patternString = ".*tuToRiAl.";
    Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
    
    在这里,我们使用了一个Pattern.CASE_INSENSITIVE进行不区分大小写的搜索,还有其他几个标志可用于不同的目的。 要了解有关此类标志的更多信息,请参阅本文档
    现在做什么:我们已经获得了Pattern实例,但是如何匹配它呢? 为此,我们需要一个Matcher实例,可以使用Pattern.matcher()方法获得该实例。 下一章让我们讨论一下。
    3) Pattern.matcher() method 方法
    在上一节中,我们学习了如何使用compile()方法获取Pattern实例。 在这里,我们将学习如何使用matcher()方法从Pattern实例获取Matcher实例。
    String content = "This is a tutorial Website!";
    String patternString = ".*tuToRiAl.*";
    Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(content);
    boolean isMatched = matcher.matches();
    System.out.println("Is it a Match?" + isMatched);
    
    4) Pattern.split() 方法
    要基于定界符(这里的定界符将使用正则表达式指定)将文本分成多个字符串,这是可以做到的,我们可以使用Pattern.split()方法。
    import java.util.regex.*;  
    class RegexExample2{  
    public static void main(String args[]){  
            String text = "ThisIsChaitanya.ItISMyWebsite";
        // Pattern for delimiter
            String patternString = "is";
            Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
            String[] myStrings = pattern.split(text);
            for(String temp: myStrings){
                System.out.println(temp);
            }
            System.out.println("Number of split strings: "+myStrings.length);
    }}
    
    第二个拆分字符串在输出中为null。在我们的Web工具中并未表现出来,在命令行编译运行下可以看到这种效果。如下图:
    java regex
  • java.util.regex.Matcher 类

    上面我们已经讨论了Matcher类。 让我们回顾一些事情:
    创建一个Matcher实例
    String content = "Some text";
    String patternString = ".*somestring.*";
    Pattern pattern = Pattern.compile(patternString);
    Matcher matcher = pattern.matcher(content);
    
    注意方法有
    1): matchs():在创建Matcher实例时,它将正则表达式与传递给Pattern.matcher()方法的整个文本进行匹配。
    ...
    Matcher matcher = pattern.matcher(content);
    boolean isMatch = matcher.matches();
    
    2): lookingAt():与matches()方法类似,不同之处在于它仅将正则表达式与文本开头匹配,而matches()在整个文本中进行搜索。
    3): find():搜索文本中正则表达式的出现。 主要在我们搜索多个事件时使用。
    4): start()end():这两种方法通常都与find()方法一起使用。 它们用于获取使用find()方法找到的匹配项的开始和结束索引。
    让我们举一个使用Matcher类的方法找出多个事件的例子:
    import java.util.regex.*;  
    class RegexExample2{  
    public static void main(String args[]){  
            String text = "ThisIsChaitanya.ItISMyWebsite";
        // Pattern for delimiter
            String patternString = "is";
            Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
            String[] myStrings = pattern.split(text);
            for(String temp: myStrings){
                System.out.println(temp);
            }
            System.out.println("Number of split strings: "+myStrings.length);
    }}
    
    现在,我们熟悉了PatternMatcher类以及将正则表达式与文本进行匹配的过程。 让我们看看定义正则表达式需要什么样的各种选择
  • 正则表达式模式

    1) 字符串文字
    假设您只想在文本中搜索特定字符串,例如 "abc",那么我们可以简单地编写如下代码:此处的文本和正则表达式都是相同的。 Pattern.matches("abc","abc")
    2) 字符
    字符类将输入文本中的单个字符与字符类中允许的多个字符进行匹配。例如,[Cc]haitanya将匹配所有出现的字符"chaitanya",并使用小写或大写C"。几个例子:
    Pattern.matches("[pqr]","abcd");由于文本中没有p,q或r,因此会给出false
    Pattern.matches("[pqr]","r");找到r时返回true
    Pattern.matches("[pqr]","pq");返回false,因为它们中的任何一个都可以是文本形式,而不是两者都可以。
    这是各种字符类构造的完整列表:
    [abc]:如果文本中只有一个(a,b或c),则它将与文本匹配。
    [^abc]:除a,b或c以外的任何单个字符(^表示取反)
    [a-zA-Z]:a到z,或A到Z(含)(范围)
    [a-d [m-p]]:a到d,或m到p:[a-dm-p](联合)
    [a-z && [def]]:其中任意一个(d,e或f)
    [a-z && [^ bc]]:a到z,b和c除外:[ad-z](减法)
    [a-z && [^ m-p]]:a到z,排除m到p:[a-lq-z]
    预定义的字符类–元字符
    这些就像编写正则表达式时可以使用的短代码。
    元字符 描述
    \d 一位数字:[0-9]
    \D 非数字:[^0-9]
    \s 空格字符:[\t\n\x0B\f\r]
    \S 非空白字符:[^\s]
    \w 文字字符:[a-zA-Z_0-9]
    \W 非文字字符:[^\w]
    例如
    Pattern.matches("\\d","1"); 将返回true
    Pattern.matches("\\D","z"); 返回true
    Pattern.matches(".p","qp"); 返回true,点(.)代表任何字符
    边界匹配器:
    边界符 描述
    ^ 匹配行的开头。
    $ 然后匹配行尾。
    \b 匹配单词边界。
    \B 匹配非单词边界。
    \A 匹配输入文本的开头。
    \G 匹配上一场比赛的结束
    \Z 匹配输入文本的末尾(如果有终止符则除外)。
    \z 匹配输入文本的结尾。
    例如
    Pattern.matches("^Hello$”,"Hello"):返回true,以Hello开头和结尾
    Pattern.matches("^Hello$”,"Namaste!Hello"):返回false,不以Hello开头
    Pattern.matches("^Hello$”,"Hello Namaste!"):返回false,不以Hello结尾
    量词:
    贪婪模式 懒人模式 所有可能项 匹配
    X? X?? X?+ 一次匹配X,或完全不匹配X(0或1次)。
    X* X*? X*+ 匹配X零次或多次。
    X+ X+? X++ X匹配1次或多次。
    X{n} X{n}? X{n}+ 与X完全匹配n次。
    X{n,} X{n,}? X{n,}+ X至少匹配n次。
    X{n, m) X{n, m)? X{n, m)+ 至少与X匹配n次,但最多匹配m次。
    几个例子:
    import java.util.regex.*;  
    class RegexExample{  
    public static void main(String args[]){  
       // It would return true if string matches exactly "tom"
       System.out.println(
         Pattern.matches("tom", "Tom")); //False
            
       /* returns true if the string matches exactly 
        * "tom" or "Tom"
        */
       System.out.println(
         Pattern.matches("[Tt]om", "Tom")); //True
       System.out.println(
         Pattern.matches("[Tt]om", "Tom")); //True
            
       /* Returns true if the string matches exactly "tim" 
        * or "Tim" or "jin" or "Jin"
        */
       System.out.println(
         Pattern.matches("[tT]im|[jJ]in", "Tim"));//True
       System.out.println(
         Pattern.matches("[tT]im|[jJ]in", "jin"));//True
            
       /* returns true if the string contains "abc" at 
        * any place
        */
       System.out.println(
         Pattern.matches(".*abc.*", "deabcpq"));//True
            
       /* returns true if the string does not have a 
        * number at the beginning
        */
       System.out.println(
         Pattern.matches("^[^\\d].*", "123abc")); //False
       System.out.println(
         Pattern.matches("^[^\\d].*", "abc123")); //True
            
       // returns true if the string contains of three letters
       System.out.println(
         Pattern.matches("[a-zA-Z][a-zA-Z][a-zA-Z]", "aPz"));//True
       System.out.println(
         Pattern.matches("[a-zA-Z][a-zA-Z][a-zA-Z]", "aAA"));//True
       System.out.println(
         Pattern.matches("[a-zA-Z][a-zA-Z][a-zA-Z]", "apZx"));//False
            
       // returns true if the string contains 0 or more non-digits
       System.out.println(
         Pattern.matches("\\D*", "abcde")); //True
       System.out.println(
         Pattern.matches("\\D*", "abcde123")); //False
            
       /* Boundary Matchers example
        * ^ denotes start of the line
        * $ denotes end of the line
        */
       System.out.println(
         Pattern.matches("^This$", "This is Chaitanya")); //False
       System.out.println(
         Pattern.matches("^This$", "This")); //True
       System.out.println(
         Pattern.matches("^This$", "Is This Chaitanya")); //False
    }
    }