Java 正则表达式详解

正则表达式是一种强大而灵活的文本处理工具,使用正则表达式能够以编程的方式构造复杂的文本模式,并对输入的字符串进行搜索,简单来说,正则表达式就是以某种方式来描述字符串。

正则表达式在线工具

一、基本语法

语法 语法解释
普通字符(字母、数字、汉字、下划线) 一个普通字符在表达式中只匹配与之相同的一个字符。
\t、\n、\t、\f 表示回车符、换行符、制表符、换页符。
[ 与 ] 使用 [] 括起来的为一个可选字符组,表示其中包含的一系列字符中任意一个字符。例如 [abc] 表示 a、b、c 中的任意一个字符; [a-z] 表示字符 a 到字符 b 中的任意一个字符,其中 - 表示一个范围。
[^ 与 ] 表示一个可选字符组的补集。例如 [^abc] 表示 a、b、c 之外的任意一个字符。
. 表示除换行符以外的任意一个字符。
\d 与 \D \d 表示 0-9 之间的任意一个字符;\D 表示 0-9 之外的任意一个字符。
\s 与 \S \s 表示包括空格、制表符、换页符等空白字符的其中任意一个字符;\S 表示空白字符以外的任意一个字符。
\w 与 \W \w 表示字母、数字、下划线中的任意一个字符;\W 表示字母、数字、下划线之外的任意一个字符。
^ 该符号不匹配任何字符,其匹配字符串开始的地方。
$ 该符号不匹配任何字符,其匹配字符串结束的地方。
\b 与 \B 不匹配任何字符,\b 表示单词的边界;\B 表示非单词边界的地方。
X? 表示 X 可以出现 0 次或 1 次。
X+ 表示 X 至少可以出现 1 次,即可以出现 1 次或多次。
X{n} 表示 X 可以出现 n 次。
X{m,n} 表示 X 至少出现 m 次,最多出现 n 次。
X{n,} 表示 X 至少出现 n 次。
? 该符号只能用在 ?、+、*、{m,n}、{n,} 的后边,用来修饰可以出现的次数按非贪婪模式进行匹配,即按照匹配模式进行最小限度的匹配。
| 用来连接两个表达式,表示或的关系。例如 X\|Y 表示 X 或 Y 中的任意字符。
() 将表达式的某个部分作为一个单元,即作一个分组,这样可以对该组整个进行操作。
\n(n 表示一个数字) 有分组的情况下,表示对分组的引用。例如 \1 表示对分组 1 的引用。
\ 该字符为转义字符,当一个符号自身有意义而又要表示这个字符的时候,需要在该字符前加一个转义字符 \ ,例如 \^ 表示 ^ ,\$ 表示 $,\\ 表示 \ 。需要用到转义字符表示的字符还有 (、)、[、]、{、}、?、+、*、|。

1、边界符

在进行匹配的时候,边界符不会匹配任何字符,只用于限定边界。

  • ^ 与 $ 分别表示的是字符串开始与结束的位置,若要求匹配的是整个字符串的内容,而不是字符串中的一部分,此时便可以使用 ^ 与 $ 加以说明。例如,^a*$ 表示的是由任意个 a 组成的字符串,而 a* 可以表示匹配整个字符串或其子串。
  • \b 表示的是单词的边缘,在要求匹配的内容是整个单词,而不是单词的一部分时,\b 就派上用场了。例如,\bTom\b 对 Tommy Tom 进行匹配,只会匹配后面的单词 Tom ,而不会匹配 Tommy 中的 Tom ,而如果不使用 \b 则两个都可以匹配。

2、匹配次数的贪婪与非贪婪

贪婪与非贪婪模式是针对量词而言的,其修饰符应该放在量词的后面。在匹配有重复字符或组出现的情况下,贪婪与非贪婪模式有不同的含义。

  • 贪婪模式下在进行匹配时,将按照最大限度的可能性进行匹配。
  • 非贪婪模式在匹配时,按照最小限度的可能性进行匹配。

例如,对于字符串 abbbabbba ,若使用正则式 a[\w]+a 进行匹配,则会按照贪婪模式进行匹配,匹配到的内容为 abbbabbba ,而使用正则式 a[\w]+?a 进行匹配,会以非贪婪模式进行匹配,匹配到的内容为 abbba。

3、分组

实际应用中,有时需要重复出现的不是单个字符,而是特定的一组字符,例如要匹配由任意个 ab 组成的字符串,这时就需要使用分组。

  • () 为分组操作符,其功能为将特定的一组字符作为一个原子(不可分)的匹配单元来看待。例如,(ab)* 表示匹配由任意个 ab 组成的字符串或子串。
  • \n ( n 表示一个数字) 表示对分组的引用,当用于匹配的正则式中有很多分组时可以使用其对分组进行引用。例如,对于分组正则式 ((23)(45)) ,其中包括三个分组 2345、23、45,编号分别为 1、2、3 ,((23)(45))\1 表示对 23452345 匹配,((23)(45))\2 表示对 234523 进行匹配。

4、示例

日期匹配 xxxx-xx-xx :^\d{4}-(0[1-9]|1[0-2])-([0-2][1-9]|3[0-1])

二、String 正则处理方法

在 Java 中有四个内置的运行正则表达式的方法,分别是 matches()、split()、replaceFirst()、replaceALL() 。注意 replace() 方法不支持正则表达式。

方法 描述
s.matches("regex") 当且仅当正则匹配整个字符串时返回 true
s.split("regex") 按匹配的正则表达式切片字符串
s.replaceFirst("regex", "replacement") 替换首次匹配的字符串片段
s.replaceAll("regex", "replacement") 替换所有匹配的字符

三、Java 正则匹配

Java 中使用正则表达式需要用到两个类,分别为 java.util.regex.Pattern 和 java.util.regex.Matcher 。

  1. 通过正则表达式创建模式对象 Pattern 。
  2. 通过模式对象 Pattern ,根据指定字符串创建匹配对象 Matcher 。
  3. 通过匹配对象 Matcher ,根据正则表达式操作字符串。
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {
    public static void main(String[] args) {
        String text = "Hello Regex!";

        Pattern pattern = Pattern.compile("\\w+");
        
        Matcher matcher = pattern.matcher(text);
        // 遍例所有匹配的序列
        while (matcher.find()) {
            System.out.print("Start index: " + matcher.start());
            System.out.print(" End index: " + matcher.end() + " ");
            System.out.println(matcher.group());
        }
        // 创建第两个模式,将空格替换为 tab
        Pattern replace = Pattern.compile("\\s+");
        Matcher matcher2 = replace.matcher(text);
        System.out.println(matcher2.replaceAll("\t"));
    }
}

运行结果:

Start index: 0 End index: 5 Hello
Start index: 6 End index: 11 Regex
Hello    Regex!

参考

  • Bruce Eckel. Java 编程思想[M]. 机械工业出版社, 2007.
  • 吴亚峰. JavaSE 6.0 编程指南[M]. 人民邮电出版社, 2007.
  • Java 正则表达式详解