Java 简明教程

Java - Regular Expressions

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

Regular Expressions in Java

regular expression 是一个特殊的字符序列,它使用模式中包含的专门语法来帮助你匹配或查找其他字符串或字符串集。它们可用于搜索、编辑或处理文本和数据。

Java Regular Expressions (Regex) Classes

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

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

  2. Matcher Class - Matcher 对象是解释模式并在给定输入字符串上执行匹配操作的引擎。与 Pattern 类类似,Matcher 未定义任何公共构造函数。可以通过对 Pattern 对象调用 matcher() 方法来获取 Matcher 对象。

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

Capturing Groups in Regular Expression

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

捕获组通过从左到右计算其左括号进行编号。例如,在表达式 A)(B© 中,存在四个这样的组 -

  1. A)(B©

  2. (A)

  3. (B©)

  4. ©

若要找出表达式中有多少组,请对匹配器对象调用 groupCount 方法。groupCount 方法返回一个 int,显示匹配器模式中存在的分组数。

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

Example

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

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");
      }
   }
}

Output

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

Regular Expression Syntax

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

Subexpression

Matches

^

匹配行的开头。

$

匹配行的末尾。

.

匹配任何单个字符(换行除外)。使用 m 选项,也可以匹配换行。

[…​]

匹配括号中的任何单字符。

[^…​]

匹配括号中不存在的任何单字符。

\A

整个字符串的开头。

\z

整个字符串的结尾。

\Z

除了允许的最终行终止符之外,整个字符串的结尾。

re*

匹配前一个表达式的 0 次或多次出现。

re+

匹配前一项 1 次或多次出现。

re?

匹配前一个表达式的 0 次或 1 次出现。

re{ n}

与前一场表达式的匹配次数完全一致

re{ n,}

与前场表达式的匹配次数相同或者超过

re{ n, m}

与前场表达式的最少的次数到最多的次数之间匹配

a

匹配 a 或 b

(re)

组合正则表达式并记住匹配的文本

(?: re)

组合正则表达式而不记住匹配的文本

(?> re)

在没有反向追踪的情况下匹配独立模式

\w

Matches the word characters.

\W

Matches the nonword characters.

\s

匹配空白字符,相当于 [\t\n\r\f]

\S

Matches the nonwhitespace.

\d

匹配数字,相当于 [0-9]

\D

Matches the nondigits.

\A

匹配字符串的开头

\Z

匹配字符串的末尾。如果存在换行符,則匹配换行符前的内容

\z

匹配字符串的末尾

\G

匹配上次匹配结束的地方

\n

引用捕获组号“n”的匹配项

\b

在方括号外,匹配单词边界。在方括号内,匹配退格符(0x08)

\B

Matches the nonword boundaries.

\n, \t, etc.

匹配换行符、回车、制表符等

\Q

转义所有字符,直到 \E

\E

Regular Expression - Matcher Class Methods

以下是有用的实例方法列表 -

Index Methods

索引方法提供有用的索引值,显示在输入字符串中精确匹配的位置 -

Sr.No.

Method & Description

1

public int start() 返回上一匹配项的起始索引。

2

public int start(int group) 在上一匹配操作期间,返回由给定分组捕获的子序列的起始索引。

3

public int end() 返回与最后一个匹配字符的偏移量。

4

public int end(int group) 在上一匹配操作期间,返回与由给定分组捕获的子序列的最后一个字符的偏移量。

Study Methods

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

Sr.No.

Method & Description

1

public boolean lookingAt() 尝试从该区域的开始匹配输入序列到该模式。

2

public boolean find() 尝试查找输入序列的下一个子序列,该子序列与该模式匹配。

3

public boolean find(int start) 重置此匹配器,然后尝试查找输入序列的下一个子序列,该子序列与该模式相符,从指定索引开始。

4

public boolean matches() 尝试将整个区域与模式匹配。

Regular Expression - Replacement Methods

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

Sr.No.

Method & Description

1

public Matcher appendReplacement(StringBuffer sb, String replacement) 实现非末端附加和替换步骤。

2

public StringBuffer appendTail(StringBuffer sb) 实现末端附加和替换步骤。

3

public String replaceAll(String replacement) 用给定的替换字符串替换源序列中所有匹配模式的子序列。

4

public String replaceFirst(String replacement) 用给定的替换字符串替换源序列中第一个匹配模式的子序列。

5

public static String quoteReplacement(String s) 针对指定字符串返回一个实际替换字符串。此方法会生成一个可在 Matcher 类的 appendReplacement 方法中用作实际替换的字符串 s

The start and end Methods

以下示例统计了单词“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());
      }
   }
}

Output

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 返回匹配的最后一个字符的索引加 1。

The matches() and lookingAt() Methods

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());
   }
}

Output

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

The replaceFirst() and replaceAll() Methods

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);
   }
}

Output

The cat says meow. All cats say meow.

The appendReplacement() and appendTail() Methods

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());
   }
}

Output

-foo-foo-foo-

Regular Expression - PatternSyntaxException Class Methods

PatternSyntaxException 是一个未经检查的异常,它表示正则表达式模式中的语法错误。PatternSyntaxException 类提供了以下方法来帮助您确定出错的原因:

Sr.No.

Method & Description

1

public String getDescription() 获取错误描述。

2

public int getIndex() 获取错误索引。

3

public String getPattern() 获取有问题的正则表达式模式。

4

public String getMessage() 返回一个多行字符串,其中包含语法错误及其索引、有问题的正则表达式模式以及模式中错误索引的可视指示。