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 表示 XY 中的任意字符。
() 将表达式的某个部分作为一个单元,即作一个分组,这样可以对该组整个进行操作。
\nn 表示一个数字) 有分组的情况下,表示对分组的引用。例如 \1 表示对分组 1 的引用。
\ 该字符为转义字符,当一个符号自身有意义而又要表示这个字符的时候,需要在该字符前加一个转义字符 \ ,例如 \^ 表示 ^\$ 表示 $\\ 表示 \ 。需要用到转义字符表示的字符还有 ()[]{}?+*|

1、边界符

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

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

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

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

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

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

3、分组

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

  • () 为分组操作符,其功能为将特定的一组字符作为一个原子(不可分)的匹配单元来看待。例如,(ab)* 表示匹配由任意个 ab 组成的字符串或子串。
  • \n ( n 表示一个数字) 表示对分组的引用,当用于匹配的正则式中有很多分组时可以使用其对分组进行引用。例如,对于分组正则式 ((23)(45)) ,其中包括三个分组 23452345,编号分别为 123((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.Patternjava.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 正则表达式详解