Java 正则表达式详解

概述

在实际开发过程中,总会遇到很多有关字符串的查找、匹配、替换、判断等操作(参加中兴的笔试时也遇到一道相关题目,泪~~),而有时候情况还比较复杂,如果直接用编程的方式来处理,代码量稍多且麻烦,往往效率低下。而这个时候,正则表达式(Regex)就是解决这类问题的利器。

正则表达式是一种模式匹配和替换的规范,一个正则就是由普通的字符(如a-zA-Z0-9)以及特殊字符(元字符)组成的文字模式,它用以描述文字主体的一个或者多个待匹配的字符。正则表达式作为表达式的一个模板,将某个字符模式与所给字符主题进行匹配。

需要说明的是,几乎每个语言都提供了正则表达式的功能,但不同语言之间的正则表达式可能略微有些差别。本文主要讲解Java中的正则表达式。

核心类

有关正则表达式的类在java.util.regex中,主要包括三个类:Pattern、Matcher、PatternSyntaxException

Pattern(模式)

pattern对象是一个正则表达式的编译表示形式。指定为字符串的正则表达式必须先编译为此类的实例。然后,将得到的模式用于创建Matcher对象(匹配器)。依照正则表达式,该对象可以和任意的字符序列匹配。执行匹配所涉及的状态都驻留在匹配器中,所以多个匹配器可以共用一个模式。

  • 临时使用Pattern
1
public static boolean matches(String regex, CharSequence input)

matches()方法编译给定正则表达式并尝试将给定输出与其匹配。其中regex是要编译的表达式,input是要匹配的字符序列。调用此便捷方法的形式如下:

1
boolean b = Pattern.matches("a*b", "aaaaab");

  • 复用Pattern
1
2
public static Pattern compile(String regex)
public Matcher matcher(CharSequence input)

其中compile将给定的正则表达式编译到模式中,而matcher则根据给定的字符序列创建与此模式的匹配器。示例如下:

1
2
3
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();

Matcher(匹配器)

通过编译pattern对字符序列执行匹配操作的引擎。通过调用模式的matcher()方法创建匹配器。

RegexSyntaxException

抛出未检查的异常,说明正则表达式中存在语法错误。

捕获组

捕获组是把多个字符当一个独立单元进行处理的方法,它通过括号内的字符分组来创建。例如,正则表达式(dog)创建了一个单一的捕获组,组里包含’d’、’o’、’g’。

捕获组是通过从左到右计算其括号来编号。例如,在表达式( (A) ( B (C) ) )中,有4个捕获组:

  • ((A)(B(C)))
  • (A)
  • (B(C))
  • (C)

可以通过matcher对象的groupCount()方法来查看有多少个捕获组。groupCount()返回一个int值,表示matcher对象当前有多少个捕获组。

还有一个特殊的组(组0),它总是代表整个表达式。该组不包括在groupCount()的返回值中。

语法




示例

查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
public static void main( String args[] ){
// 按指定模式在字符串查找
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
System.out.println("groupCount: " + m.groupCount());
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");
}
}
}

以上实例编译运行结果如下:

1
2
3
4
groupCount: 3
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

最后

Java正则的功用还有很多,事实上只要是字符处理,就没有正则做不到的事情存在。(当然,正则解释时较耗时间就是了|||……)

参考文档