Java - 正则表达式


Java 提供了 java.util.regex 包用于与正则表达式进行模式匹配。Java正则表达式与Perl编程语言非常相似并且非常容易学习。

正则表达式是一种特殊的字符序列,可帮助您使用模式中保存的专用语法来匹配或查找其他字符串或字符串集。它们可用于搜索、编辑或操作文本和数据。

java.util.regex 包主要包含以下三个类 -

  • Pattern 类- Pattern 对象是正则表达式的编译表示。Pattern 类不提供公共构造函数。要创建模式,必须首先调用其公共静态compile()方法之一,然后该方法将返回Pattern 对象。这些方法接受正则表达式作为第一个参数。

  • Matcher 类- Matcher 对象是解释模式并对输入字符串执行匹配操作的引擎。与 Pattern 类一样,Matcher 没有定义公共构造函数。您可以通过调用Pattern 对象的matcher()方法来获取 Matcher 对象。

  • PatternSyntaxException - PatternSyntaxException 对象是一个未经检查的异常,指示正则表达式模式中的语法错误。

捕获组

捕获组是将多个字符视为一个单元的一种方法。它们是通过将要分组的字符放在一组括号内来创建的。例如,正则表达式 (dog) 创建一个包含字母“d”、“o”和“g”的组。

捕获组通过从左到右数其左括号来编号。例如,在表达式 ((A)(B(C))) 中,有四个这样的组 -

  • ((A)(B(C)))
  • (A)
  • (公元前))
  • (C)

要了解表达式中存在多少个组,请调用匹配器对象的 groupCount 方法。groupCount 方法返回一个int,显示匹配器模式中存在的捕获组的数量。

还有一个特殊的组,组 0,它始终代表整个表达式。该组不包含在 groupCount 报告的总数中。

例子

以下示例说明如何从给定的字母数字字符串中查找数字字符串 -

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   public static void main( String args[] ) {
      // String to be scanned to find the pattern.
      String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";

      // Create a Pattern object
      Pattern r = Pattern.compile(pattern);

      // Now create matcher object.
      Matcher m = r.matcher(line);
      if (m.find( )) {
         System.out.println("Found value: " + m.group(0) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
      }else {
         System.out.println("NO MATCH");
      }
   }
}

输出

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

正则表达式语法

下面的表格列出了 Java 中可用的所有正则表达式元字符语法 -

子表达式 火柴
^ 匹配行的开头。
$ 匹配行尾。
匹配除换行符之外的任何单个字符。使用m选项也可以匹配换行符。
[...] 匹配括号中的任何单个字符。
[^...] 匹配不在括号中的任何单个字符。
\A 整个字符串的开头。
\z 整个字符串的结尾。
\Z 整个字符串的结尾(允许的最后行终止符除外)。
关于* 匹配前面的表达式出现 0 次或多次。
重新+ 匹配 1 个或多个前一个事物。
关于? 匹配前面表达式的 0 次或 1 次出现。
重新{n} 精确匹配前面表达式的 n 次出现。
重新{n,} 匹配前面的表达式出现 n 次或多次。
重新{n,m} 匹配前面表达式至少出现 n 次、最多出现 m 次。
一个| 乙 匹配 a 或 b。
(关于) 对正则表达式进行分组并记住匹配的文本。
(?: 关于) 对正则表达式进行分组,而不记住匹配的文本。
(?> 重新) 匹配独立模式而不回溯。
\w 匹配单词字符。
\W 匹配非单词字符。
\s 匹配空白。相当于[\t\n\r\f]。
\S 匹配非空白。
\d 匹配数字。相当于[0-9]。
\D 匹配非数字。
\A 匹配字符串的开头。
\Z 匹配字符串的结尾。如果存在换行符,则它会在换行符之前匹配。
\z 匹配字符串的结尾。
\G 匹配上一场比赛结束的点。
\n 向后引用捕获组编号“n”。
\b 匹配括号外的单词边界。匹配括号内的退格键 (0x08)。
\B 匹配非单词边界。
\n、\t 等 匹配换行符、回车符、制表符等。
\问 转义(引用)\E 之前的所有字符。
\E 结束以 \Q 开头的引用。

Matcher 类的方法

这是有用的实例方法的列表 -

索引方法

索引方法提供了有用的索引值,可以准确显示在输入字符串中找到匹配项的位置 -

先生。 方法及说明
1

公共 int 开始()

返回上一场比赛的开始索引。

2

公共 int 开始(int 组)

返回给定组在上一次匹配操作期间捕获的子序列的起始索引。

3

公共int结束()

返回最后一个匹配字符之后的偏移量。

4

公共int结束(int组)

返回在上一次匹配操作期间给定组捕获的子序列的最后一个字符之后的偏移量。

研究方法

研究方法检查输入字符串并返回一个布尔值,指示是否找到模式 -

先生。 方法及说明
1

公共布尔型lookingAt()

尝试从区域的开头开始与模式匹配输入序列。

2

公共布尔查找()

尝试查找输入序列中与模式匹配的下一个子序列。

3

公共布尔查找(int start)

重置此匹配器,然后尝试从指定索引处开始查找与模式匹配的输入序列的下一个子序列。

4

公共布尔匹配()

尝试将整个区域与模式进行匹配。

更换方法

替换方法是替换输入字符串中文本的有用方法 -

先生。 方法及说明
1

公共匹配器appendReplacement(StringBuffer sb,字符串替换)

实现非终止附加和替换步骤。

2

公共 StringBuffer appendTail(StringBuffer sb)

实现终端追加和替换步骤。

3

公共字符串replaceAll(字符串替换)

用给定的替换字符串替换与模式匹配的输入序列的每个子序列。

4

公共字符串replaceFirst(字符串替换)

用给定的替换字符串替换与模式匹配的输入序列的第一个子序列。

5

公共静态字符串 quoteReplacement(String s)

返回指定字符串的文字替换字符串。此方法生成一个 String,它将用作Matcher 类的appendReplacement 方法中的文字替换。

开始和结束方法

以下是计算单词“cat”在输入字符串中出现的次数的示例 -

例子

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "\\bcat\\b";
   private static final String INPUT = "cat cat cat cattie cat";

   public static void main( String args[] ) {
      Pattern p = Pattern.compile(REGEX);
      Matcher m = p.matcher(INPUT);   // get a matcher object
      int count = 0;

      while(m.find()) {
         count++;
         System.out.println("Match number "+count);
         System.out.println("start(): "+m.start());
         System.out.println("end(): "+m.end());
      }
   }
}

输出

Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

您可以看到,此示例使用单词边界来确保字母“c”“a”“t”不仅仅是较长单词中的子字符串。它还提供了一些有关输入字符串中发生匹配的位置的有用信息。

start 方法返回给定组在上一次匹配操作期间捕获的子序列的开始索引,end 返回最后一个匹配的字符的索引加一。

matches 和lookingAt 方法

matches 和lookingAt 方法都尝试将输入序列与模式进行匹配。但不同之处在于,matches 需要匹配整个输入序列,而lookingAt 则不需要。

两种方法始终从输入字符串的开头开始。这是解释功能的示例 -

例子

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "foo";
   private static final String INPUT = "fooooooooooooooooo";
   private static Pattern pattern;
   private static Matcher matcher;

   public static void main( String args[] ) {
      pattern = Pattern.compile(REGEX);
      matcher = pattern.matcher(INPUT);

      System.out.println("Current REGEX is: "+REGEX);
      System.out.println("Current INPUT is: "+INPUT);

      System.out.println("lookingAt(): "+matcher.lookingAt());
      System.out.println("matches(): "+matcher.matches());
   }
}

输出

Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

ReplaceFirst 和 ReplaceAll 方法

ReplaceFirst 和 ReplaceAll 方法替换与给定正则表达式匹配的文本。正如其名称所示,replaceFirst 替换第一个出现的位置,replaceAll 替换所有出现的位置。

这是解释功能的示例 -

例子

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "dog";
   private static String INPUT = "The dog says meow. " + "All dogs say meow.";
   private static String REPLACE = "cat";

   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      
      // get a matcher object
      Matcher m = p.matcher(INPUT); 
      INPUT = m.replaceAll(REPLACE);
      System.out.println(INPUT);
   }
}

输出

The cat says meow. All cats say meow.

AppendReplacement 和 AppendTail 方法

Matcher 类还提供了用于文本替换的appendReplacement 和appendTail 方法。

这是解释功能的示例 -

例子

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "a*b";
   private static String INPUT = "aabfooaabfooabfoob";
   private static String REPLACE = "-";
   public static void main(String[] args) {

      Pattern p = Pattern.compile(REGEX);
      
      // get a matcher object
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();
      while(m.find()) {
         m.appendReplacement(sb, REPLACE);
      }
      m.appendTail(sb);
      System.out.println(sb.toString());
   }
}

输出

-foo-foo-foo-

PatternSyntaxException 类方法

PatternSyntaxException 是未经检查的异常,指示正则表达式模式中的语法错误。PatternSyntaxException 类提供以下方法来帮助您确定出了什么问题 -

先生。 方法及说明
1

公共字符串 getDescription()

检索错误的描述。

2

公共 int getIndex()

检索错误索引。

3

公共字符串 getPattern()

检索错误的正则表达式模式。

4

公共字符串 getMessage()

返回一个多行字符串,其中包含语法错误及其索引的描述、错误的正则表达式模式以及模式内错误索引的可视指示。