Java 教程

Java 控制语句

面向对象编程

Java 内置类

Java 文件处理

Java 错误和异常

Java 多线程

Java 同步

Java 网络

Java 集合

Java 接口

Java 数据结构

Java 集合算法

高级 Java

Java 杂项

Java API 和框架

Java 类参考

Java 有用资源

Java - 正则表达式



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

Java 中的正则表达式

正则表达式是用于匹配或查找其他字符串或字符串集的特殊字符序列,使用包含在模式中的专门语法。它们可用于搜索、编辑或处理文本和数据。

Java 正则表达式 (Regex) 类

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)
  • (B(C))
  • (C)

要找出表达式中存在多少个组,请在 matcher 对象上调用 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 整个字符串的结尾,除了允许的最终行终止符。
re* 匹配前一个表达式的 0 个或多个出现。
re+ 匹配前一个表达式的 1 个或多个出现。
re? 匹配前一个表达式的 0 个或 1 个出现。
re{ n} 精确匹配前一个表达式的 n 个出现。
re{ n,} 匹配前一个表达式的 n 个或更多出现。
re{ n, m} 至少匹配前一个表达式的 n 个出现,最多 m 个出现。
a| b 匹配 a 或 b。
(re) 对正则表达式进行分组并记住匹配的文本。
(?: re) 对正则表达式进行分组,但不记住匹配的文本。
(?> re) 匹配不回溯的独立模式。
\w 匹配单词字符。
\W 匹配非单词字符。
\s 匹配空白字符。等效于 [\t\n\r\f]。
\S 匹配非空白字符。
\d 匹配数字。等效于 [0-9]。
\D 匹配非数字。

\A 匹配字符串的开头。
\Z 匹配字符串的结尾。如果存在换行符,则匹配换行符之前的字符。
\z 匹配字符串的结尾。
\G 匹配上次匹配结束的位置。
\n 反向引用捕获组编号为“n”的组。
\b 在括号外部匹配单词边界。在括号内部匹配退格键 (0x08)。
\B 匹配非单词边界。
\n, \t, 等。 匹配换行符、回车符、制表符等。
\Q 转义(引用)直到 \E 之前的所有字符。
\E 结束以 \Q 开始的引用。

正则表达式 - Matcher 类方法

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

索引方法

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

序号 方法及描述
1

public int start()

返回上一次匹配的起始索引。

2

public int start(int group)

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

3

public int end()

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

4

public int end(int group)

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

研究方法

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

序号 方法及描述
1

public boolean lookingAt()

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

2

public boolean find()

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

3

public boolean find(int start)

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

4

public boolean matches()

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

正则表达式 - 替换方法

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

序号 方法及描述
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

start 和 end 方法

以下示例计算单词“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

public String getDescription()

检索错误的描述。

2

public int getIndex()

检索错误索引。

3

public String getPattern()

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

4

public String getMessage()

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

广告