总述

正则表达式有一系列字符和特殊字符(称为元字符)组合而成,用来匹配和描述特定字符串的特定模式,提供了一种灵活且强大的方式来查找、替换、验证和提取文本数据。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

正则表达式元字符和特性

字符匹配

  • 普通字符:普通字符指没有显示指定为元字符的所有可打印和不可打印字符,包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。普通字符按照字面意义进行匹配,例如匹配字母 “a” 将匹配到文本中的 “a” 字符。
  • 元字符:元字符具有特殊的含义,例如 \d 匹配任意数字字符,\w 匹配任意字母数字字符,. 匹配任意字符(除换行符)等。

字符类

一般字符类

字符 描述
[ ] 匹配括号内的任意一个字符,如果没有量词修饰时,代表方括号中元素有且仅有一个。例如,[abc] 匹配字符 “a”, “b” 或 “c”。
[^ ] 匹配除了括号内的字符以外的任意一个字符。例如,[^abc] 匹配除了字符 “a”, “b” 或 “c” 以外的任意字符。
\cx 匹配由x指明的控制字符。例如,\cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
[A-Z] 匹配所有大写字母
\w 匹配数字字母下划线,等价于[A-Za-z0-9_]
\d 匹配任意一个阿拉伯数字 ,等价于[0-9]
\f 匹配一个换页符。等价于 \x0c\cL
\n 匹配一个换行符。等价于 \x0a\cJ
\r 匹配一个回车符。等价于 \x0d\cM
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 ,[\s\S]就可以代表任何字符了
\t 匹配一个制表符。等价于 \x09\cI
\v 匹配一个垂直制表符。等价于 \x0b\cK

特殊字符

量词

  • *:匹配前面的模式零次或多次。
  • +:匹配前面的模式一次或多次。
  • ?:匹配前面的模式零次或一次,或者指明一个非贪婪限定符。
  • {n}:匹配前面的模式恰好 n 次。
  • {n,}:匹配前面的模式至少 n 次。
  • {n,m}:匹配前面的模式至少 n 次且不超过 m 次。

*+等两次限定符都是贪婪的,会尽可能多的匹配文字,只有在他们的后面加上一个?就可以实现非贪婪或者最小匹配
例如,对于字符串15cdcnd<yesterday>today<tomorrow>cndsjn

  • 贪婪匹配:/<.*>/, 该正则表达式匹配从<> 之间的所有内容,会匹配到<yesterday>today<tomorrow>字符串
  • 非贪婪匹配: /<.*?>/,该正则表达式匹配第一个<到第一个> 之间的所有内容,会匹配到<yesterday>

边界匹配(定位符)

  • ^:匹配字符串的开头。
  • $:匹配字符串的结尾。
  • \b:匹配单词边界,相当于单词和空格之间的元素。\bCha匹配单词开头的Chater\b匹配字符串结尾的ter
  • \B:匹配非单词边界。

分组和捕获

  • ( ):用于分组和捕获子表达式。
  • (?: ):用于分组但不捕获表达式。

其他

  • \:转义字符,用于匹配特殊字符本身。
  • .:匹配任意字符(除换行符\n\r)。
  • |: 用于制定多个模式的选择。例如,(a|b)就当与匹配一个a或者b

以上特殊字符在匹配的时候,均使用转义字符。例如利用\(匹配(

匹配

?=等的用法

  • ?= : exp1(?=exp2),查找 exp2 前面的 exp1
  • ?<= : (?<=exp2)exp1:查找 exp2 后面的 exp1。
  • ?! :exp1(?!exp2):查找后面不是 exp2 的 exp1。
  • ?<! :(?<!exp2)exp1:查找前面不是 exp2 的 exp1。

修饰符(标记)

标记不写在正则表达式里面, 标记位于表达式之外,同一表示式可以有多个标记
例如/pattern/flags
下表列出了正则表达式常用的修饰符:

修饰符 含义 描述
i ignore - 不区分大小写 将匹配设置为不区分大小写,搜索时不区分大小写:A 和 a 没有区别。
g global - 全局匹配 查找所有的匹配项。
m multi line - 多行匹配 使边界字符 ^$ 匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾。
s 特殊字符圆点 . 中包含换行符 \n 默认情况下的圆点 . 是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后,. 中包含换行符 \n

Java中的正则表达式学习

Java中,正则表达式通过java.util.regex包中的PatternMatcher类实现,同时String类也直接支持部分正则操作

核心类

  • Pattern类:Pattern类没有公共构造方法,创建Pattern对象时调用其静态编译方法,接受正则表达式作为参数,返回Pattern对象
  • Matcher类:对输入字符串进行解释和匹配操作的引擎。Matcher也没有公共构造方法,通过调用Pattern对象的matcher方法来获得一个Matcher对象
1
2
3
4
5
// 对象创建示例
//Pattern创建,匹配数字后面 跟随字母的字符串
Pattern pattern = Pattern.compile("\\d+[a-zA-Z]*");
// Matcher创建,利用pattern对象调用matcher方法,并且传入字符串
Matcher matcher = pattern.matcher("cdbdu2652652scvfev262cdcdxsx 151cec"); // 传入待处理字符串

注意:Java中对特殊字符进行转义时使用\\,例如\\d匹配数字
贪婪模式:默认量词为贪婪匹配,可用 *?+? 切换为非贪婪模式。

匹配、查找、提取

匹配

  • 简单完全匹配:利用Pattern.matches(regex,input)或者matcher.matches()方法实现完全匹配
1
2
3
4
5
6
7
8
// 方法一
boolean isMatch = Pattern.matches("a*b", "aaab"); // true,aaab完全符合a*b的正则模式
// regex参数处也可以直接传入正则表达式编译过后的pattern对象

// 方法二
Pattern pattern = Pattern.compile("a*b");
Matcher matcher = pattern.matcher("aaab");
boolean isMatch = matcher.matches();
  • 查找所有匹配项
1
2
3
4
5
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("abc12 3xyz456");
while (matcher.find()) {
System.out.println(matcher.group()); // 输出 12, 3, 456
}

提取分组内容

  • matcher.find() 查找下一个匹配项
  • matcher.group(n) 获取第n个分组内容(从1开始)。 matcher.group(0)是输入字符串本身
    提取分组时正则表达式中必须要有括号,用于捕获,不在括号内的不用于分组
1
2
3
4
5
6
Pattern pattern = Pattern.compile("(\\d{3})-(\\d{4})");
Matcher matcher = pattern.matcher("电话: 010-1234");
if (matcher.find()) {
String areaCode = matcher.group(1); // "010"
String localNumber = matcher.group(2); // "1234"
}

字符串替换

1
2
3
String text = "1990-01-20";
String replaced = text.replaceAll("(\\d{4})-(\\d{2})-(\\d{2})", "$3/$2/$1");
// 结果: "20/01/1990"

分割字符串

1
String[] parts = "a,b,c".split("\\s*,\\s*"); // 结果: ["a", "b", "c"]

本文参考菜鸟教程和deepseek,豆包