- 正则表达式 是一种强大而灵活的 文本处理工具 。
- 使用 正则表达式 能够以编程的方式,构造复杂的 文本模式/模板,并对输入的字符串进行搜索 。
- 一旦找到了匹配这些 模式/模板 的部分,就能够随心所欲地对它们进行处理。
- 正则表达式能够解决各种 字符串 处理相关的问题:
- 匹配、搜索、替换、分割、验证。
一、基础语法 与 元字符
1、字符匹配
- 列表
元字符 | 说明 | 示例 | 匹配内容 |
---|---|---|---|
. | 匹配任意一个字符(除换行符) | a.c:以 a 开头,以 c 结尾,中间任意一个字符的三个字符的字符串。 | abc,a1c |
B | 匹配指定字符 B | B | B |
\d | 匹配单个数字(等价于 [0-9]) | \d{3}(\d)?: + 3 个或 4 个数字的字符串。 | 123,2456 |
\D | 匹配单个非数字(等价于 [^0-9]) | \D+ | abc,@#$ |
\w | 匹配单个单词字符([a-zA-Z0-9_]) | \w+ | user123,name |
\W | 匹配单个非单词字符 | \W+\d{2}:以至少 1 个非数字字母字符开头,2 个数字字符结尾的字符串 | #31,#?%@10 |
\s | 匹配空白字符(空格、制表符等) | \s+ | ,\t |
\S | 匹配非空白字符 | \S+ | abc,123 |
- .:匹配除 "\r\n" 之外的任何一个字符(甚至 . 本身)。
- 若要匹配包括 “\r\n” 在内的任何一个字符,请使用诸如 “[\s\S]” 之类的模式。
2、转义字符
- 列表
转义字符 | 说明 | 匹配内容 |
---|---|---|
\ | 转义号 | 如:Java 正则表达式中,两个 \\ 代表 一个 \ |
\t | 匹配 水平制表符(Tab) | ASCII 0x09 |
\n | 匹配 换行符(LF, Line Feed) | ASCII 0x0A |
\r | 匹配 回车符(CR, Carriage Return) | ASCII 0x0D |
\f | 匹配 换页符(Form Feed) | ASCII 0x0C |
\xhh | 匹配 十六进制 的 ASCII 字符 | \x21 → !、 \x41 → A |
\uhhhh | 匹配 十六进制 的 Unicode 字符 | \u00A9 → ©、\u4e2d → 中 |
- \n:换行符【\n\n 是 Linux 匹配空白行 】
- 同时适用于 Windows 和 Linux 的正则表达式应包含:一个可选的 \r 和一个必须被匹配的 \n
- \r:回车符【\r\n 是 Windows 所使用的文本行结束标签】
3、选择匹配符 / 分支结构
语法 | 说明 | 示例 | 匹配内容 |
---|---|---|---|
a|b | 匹配 a 或 b 任意一个字符。 | a|b | a,b |
z|food | 匹配 z 或 food 任意一个。 | ||
(z|f)ood | 匹配 zood或 food 任意一个。 |
4、字符集合
- 列表
语法 | 说明 | 示例 | 匹配内容 |
---|---|---|---|
abc | 只匹配 abc | abc | abc |
[abc] | 匹配 a 或 b 或 c 任意一个字符。 | [aeiou] | a,e |
[.*+] | 匹配 . 或 * 或 + 任意一个字符。 | [.*+] | .,* |
[.*+]] | 匹配 . 或 * 或 + 或 ] 任意一个字符。 | [.*+]] | .,] |
[.*+-] | 匹配 . 或 * 或 + 或 - 任意一个字符。 - 在末尾不表示范围。 | [.*+-] | .,- |
[a-f] | 匹配 a 到 f 其中的任意一个字符 | [a-f] | a,b |
[a-zA-Z] | 匹配 a 到 z 和 A 到 Z 两个范围的并集中任意一个字符 | [A-Za-z]+ | Hello |
[a-zA-Z0-9_-] | 匹配小写字母、大写字母、数字、下划线、连线符 (-) 中的任意一个字符。 | [a-zA-Z0-9_-] | -,_ |
[abc[hij]] | 匹配a或b或c或h或i或j任意一个字符 + 等价于 [abchij],匹配两者的并集。 | ||
[a-z&&[hij]] | 小写字母 a 到 z 和字符 h、i、j 的交集 + 匹配结果:h或i或j任意一个字符。 | ||
[^abc] | 匹配不是 a、b、c 的任何一个字符 | [^abc] | d,# |
[^a-f] | 匹配不是 a、b、c、d、e、f 的任何一个字符 | [^a-f] | h,# |
[a-z&&[^hij]] | 小写字母 a 到 z 和不是 h、i、j 的任何一个字符的****交集 + 匹配结果:不是 h、i、j 的任何一个小写字母 | [a-z&&[^hij]] | a,b |
5、量词
- 列表
量词 | 说明 | 示例 | 匹配内容 |
---|---|---|---|
* | 匹配 0 次或多次,等价于 {0,} | a* | a,aaaa |
+ | 匹配 1 次或多次,等价于 {1,} | \d+ | 1,123 |
? | 匹配 0 次或 1 次,等价于 {0,1} | colou?r | color,colour |
{n} | 精确匹配 n 次 | \d{4} | 2023,1234 |
{n,} | 至少匹配 n 次 | \w{3,} | abc,12345 |
{0,n} | 匹配最多 n 次 | \w{0,3} | a,123 |
{n,m} | 匹配 n 到 m 次(包含: n 次 和 m 次) | a{2,4} | aa,aaaa |
6、边界与位置
- 列表
元字符 | 说明 | 示例 | 匹配内容 |
---|---|---|---|
^ | 匹配字符的开头 (多行模式下匹配行首) | ^Hello | Hello 开头的行 |
$ | 匹配字符的结尾 (多行模式下匹配行尾) | end$ | end 结尾的行 |
\b | 匹配单词边界 | \bcat\b | “cat”, “a cat” |
\B | 匹配非单词边界的位置 | \B-\B | “well-known” |
- 单词字符:字母、数字、下划线([a-zA-Z0-9_])。
- \b 用来匹配 单词的边界位置,即:
- 单词的 开始(前一个字符是非单词字符。如:空格、标点)。
- 单词的 结束(后一个字符是非单词字符)。
// 匹配独立单词
\bcat\b
✅ 匹配:"cat", "a cat" 中的 cat
❌ 不匹配:"category", "cat123"(非独立单词)
// 提取单词前缀
\bJava\w*
✅ 匹配:"Java", "JavaScript"
❌ 不匹配:"IJava"(前缀有非单词字符)
// 开头是单词字符,结尾是数字
^\w+\b.*\d$
✅ 匹配:"Pass123"
❌ 不匹配:"123Pass"(开头是数字,结尾是单词字符)
- \B 匹配 非单词边界的位置,即:
- 单词字符 之间(如:aa 中的两个 a 之间)。
- 非单词字符 之间(如:## 中的两个 # 之间)。
// 匹配连续两个相同字母(如 "oo")
(\w)\B\1
✅ 匹配:"book" 中的 oo
❌ 不匹配:"boss"(单个 s)
// 匹配不在单词边界的连字符
\B-\B
✅ 匹配:"well-known" 中的 -
❌ 不匹配:"end-" 或 "-start"(连字符在边界)
// 匹配被单词字符包围的 @
\B@\B
✅ 匹配:"user@domain.com" 中的 @
❌ 不匹配:"@mention" 或 "email@"(@ 在边界)
7、修饰符
- 修饰符:用于调整正则表达式的匹配行为。
- 如:忽略大小写、跨行匹配、全局搜索、启用 Unicode 模式。
修饰符 | 名称(通用) | 作用 |
---|---|---|
i | 忽略大小写 | 匹配时不区分大小写 |
m | 多行模式 | 使 ^ 和 $ 匹配每行的开头和结尾(而非整个字符串的首尾) |
s | 单行模式(DOTALL) | 允许 . 匹配包括换行符(\n)在内的任意字符 |
g | 全局匹配 | 查找所有匹配项(而非在第一次匹配后停止) |
u | Unicode 模式 | 启用完整的 Unicode 支持(如匹配四字节字符) |
x | 宽松模式 | 忽略正则中的空白和注释(增强可读性) |
String content = "a11c8abcABCaBc";
// 匹配 abc 字符串【默认区分大小写】
String regStr = "abc";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
/*
找到:abc
*/
while (matcher.find()){
System.out.println("1找到:" + matcher.group());
}
// 匹配 abc 字符串【默认不区分大小写】
regStr = "(?i)abc";
pattern = Pattern.compile(regStr);
matcher = pattern.matcher(content);
/*
2找到:abc
2找到:ABC
2找到:aBc
*/
while (matcher.find()){
System.out.println("2找到:" + matcher.group());
}
// 表示 匹配 abc ,中间字母 b 不区分大小写 。
regStr = "a((?i)B)c";
pattern = Pattern.compile(regStr);
matcher = pattern.matcher(content);
/*
3找到:abc
3找到:aBc
*/
while (matcher.find()){
System.out.println("3找到:" + matcher.group());
}
// 表示 匹配 abc ,bc 不区分大小写 。
regStr = "a(?i)bc";
pattern = Pattern.compile(regStr);
matcher = pattern.matcher(content);
/*
3找到:abc
3找到:aBc
*/
while (matcher.find()){
System.out.println("4找到:" + matcher.group());
}
二、分组 – (pattern)
1、定义
- 分组 :
- 将表达式从左到右按照 () 进行分组。
2、分组编号规则
- 从左到右:
- 按左括号 “(”出现顺序编号,从 1 开始分组编号。
- 因为, 0 表示整个表达式。
- 嵌套分组:
- 外层先编号 ,再处理内层。
// 分组1: A(B(C)), 分组2: B(C), 分组3: C
(A(B(C)))
- 分组示例:
// Java 提取分组内容
Matcher m = Pattern.compile("(\\d+)-(\\d+)").matcher("2025-05");
if (m.find()) {
// 2025-05
System.out.println(m.group(0));
// 2025
System.out.println(m.group(1));
// 05
System.out.println(m.group(2));
}
三、捕获分组 – (pattern)
- 将 () 内的表达式 / 子模式称为“捕获组”。
- 捕获分组:
- 将捕获组作为一个整体模板去匹配,将匹配到的子串进行捕获 (存储),供后续用索引或名称引用
- 示例:
- (abc) :将 abc 作为一个整体模板去进行匹配,并捕获(存储)匹配到的 abc 。
- (…):用于匹配 任意三个字符,并捕获(存储)任意三个字符 。
- 核心作用 :提取数据、反向引用、替换操作。
1、普通捕获分组 – (pattern)
- 正则表达式 (\d{4})-(\d{2}) 将 2025-05 拆分出两个捕获组。
// 匹配 "2025-05",分组 1 为年,分组 2 为月
(\d{4})-(\d{2})
- 可以通过编号来获取匹配的分组。
- group(0) :完整的字符串。
String text = "2025-05-16";
Pattern pattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
// 2025-05-16
System.out.println(matcher.group(0));
// "2025"
System.out.println(matcher.group(1));
// "05"
System.out.println(matcher.group(2));
// "16"
System.out.println(matcher.group(3));
}
2、命名捕获分组 – (?pattern)
- 每一个以左括号 “(” 开始的捕获组,都紧跟着“?”。然后,才是正则表达式。
// 分组名:year、month
(?<year>\d{4})-(?<month>\d{2})
- 可以通过命名来获取匹配的分组,也可以用编号来获取匹配的分组。
String text = "2025-05-16";
Pattern pattern = Pattern.compile("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})");
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
// {year=1, day=3, month=2}
System.out.println(matcher.namedGroups());;
// 2025-05-16
System.out.println(matcher.group(0));
// "2025"
System.out.println(matcher.group("year"));
// "2025"
System.out.println(matcher.group(1));
// "05"
System.out.println(matcher.group("month"));
// "16"
System.out.println(matcher.group("day"));
}
3、分组引用 / 反向引用 / 回溯引用
- 允许在 正则表达式 中引用之前捕获的分组内容,常用于匹配重复或对称 的结构。
- 引用 的使用格式:
- 正则表达式内部使用:\\组号 。
- 正则表达式外部使用:$组号 。
- 1、按编号引用 – 正则内部使用 \\组号(如:\\1)。
(\d{3})-\1 # 匹配重复的三位数字,如 "123-123"
<(\w+)>.*?</\1> # 匹配对称标签,如 <div>内容</div>
// 匹配 "123-123"
Pattern pattern = Pattern.compile("(\\d{3})-\\1");
Matcher matcher = pattern.matcher("123-123");
// true
System.out.println(matcher.find());
// 匹配重复单词,如 "the the"
Pattern pattern = Pattern.compile("\\b(\\w+)\\s+\\1\\b");
Matcher matcher = pattern.matcher("the the");
// true
System.out.println(matcher.find());
- 2、按编号引用 – 正则外部使用 $组号(如:$1)。
// Java 代码:YYYY-MM-DD → DD/MM/YYYY
String replaced1 = "2025-05-16".replaceAll(
"(\\d{4})-(\\d{2})-(\\d{2})",
"$3/$2/$1"
);
// 16/05/2025
System.out.println(replaced1);
// 隐藏手机号
// 用 $1 来引用第一个捕获组 (手机号的前三位),用 $2 来引用第二个捕获组 (手机号的后四位)。
String replaced2 = "13812345678".replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
// 138****5678
System.out.println(replaced2);
- 3、按名称引用:${name}(需命名分组支持)。
# 匹配对称标签(命名分组)
<(?<tag>\w+)>.*?</\k<tag>>
// Java 代码:YYYY-MM-DD → DD/MM/YYYY
String replaced = "2025-05-16".replaceAll(
"(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})",
"${day}/${month}/${year}"
);
// 16/05/2025
System.out.println(replaced);
四、非捕获分组
- 捕获分组 与 非捕获分组 的区别:
- 捕获分组 会存储 分组 匹配到的内容。
- 即:当 0 < n <= 分组数量 时 ,可以用 matcher.group(n) 获取到分组存储 的数据。
- 非捕获分组 不会存储 分组 匹配到的内容。
- 即:当 0 < n <= 分组数量 时 ,用 matcher.group(n) 去获取到分组的数据会报错。
String content = "hello希望教育,希望工程,树理希望小学";
// 选择匹配
// String regStr = "希望教育|希望工程|希望小学";
// 与 选择匹配 等价的 非捕获分组写法
String regStr = "希望(?:教育|工程|小学)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
/*
找到:希望教育
找到:希望工程
找到:希望小学
*/
while (matcher.find()){
// matcher.group() 内部调用的就是 matcher.group(0) 。
System.out.println("找到:" + matcher.group());
// 运行报错:Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 1 .
// 体现了,非捕获分组,不存储 分组表达式匹配到的内容。
// System.out.println(matcher.group(1));
}
// 捕获分组
regStr = "希望(教育|工程|小学)";
pattern = Pattern.compile(regStr);
matcher = pattern.matcher(content);
/*
找到:希望教育
教育
找到:希望工程
工程
找到:希望小学
小学
*/
while (matcher.find()){
// matcher.group() 内部调用的就是 matcher.group(0) 。
System.out.println("找到:" + matcher.group());
// 体现了,捕获分组,存储 分组表达式匹配到的内容。
System.out.println(matcher.group(1));
}
1、普通非捕获分组 – (?:pattern)
- 在左括号后紧跟 ?: 。然后,再加上正则表达式,构成 非捕获组 (?:pattern) 。
- 将 () 内 ?: 后边的表达式作为一个整体模板去进行匹配,但不捕获(不存储)匹配到的文本。
- 示例:
- (?:abc) :将 abc 作为一个整体模板去进行匹配,但不捕获(不存储)abc。
- (?:…):用于匹配 任意三个字符,但不捕获(不存储)匹配到的 任意三个字符。
- 功能作用:
- 非捕获组 仅作为逻辑分组,不保存匹配的子字符串,减少内存占用。可以提升匹配速度 。
- 应用场景:
- 一些表达式中,不得不使用 (),但又不需要保存 () 中子表达式匹配的内容。
- 可以用 非捕获组 来抵消使用 () 带来的副作用。
2、原子分组 – (?>pattern) 特殊的 非捕获分组
- 原子分组(Atomic Group)/ 固化分组:
- 是一种 特殊的 非捕获分组 ,它有一个特殊的功能 – 禁止回溯(backtracking)。
- 核心特性:
- 禁止回溯:(?>pattern) 内 匹配成功 后,正则引擎不会回退尝试其它可能的 匹配路径。
- 即使,后续匹配失败也不会回溯到该分组内部尝试其他可能性
- 优化性能:避免复杂正则的灾难性回溯(Catastrophic Backtracking)。
- 改变匹配逻辑:可能影响 整体匹配结果(因提前锁定路径)。
- 回溯 的 原理:(如:普通分组 a(bc|b)c 匹配 abc 时):
- 引擎会先尝试匹配分支 bc,匹配到之后。再尝试用剩余的字符去匹配右括号后边的 c 。
- 此时,字符 abc 已经没有剩余的字符去匹配右括号后边的 c 。因此,会失败。
- 当去匹配右括号后边的 c 失败后,回溯到分组内尝试匹配分支 b,匹配到之后。
- 再尝试用剩余的字符 c 去匹配右括号后边的 c 。最终,成功匹配。
- 禁止回溯 的 原理:(如:原子分组 a(?>bc|b)c 匹配 abc 时):
- 引擎会先尝试匹配分支 bc,匹配到之后。再尝试用剩余的字符去匹配右括号后边的 c 。
- 此时,字符 abc 已经没有剩余的字符去匹配右括号后边的 c 。因此,会失败。
- 匹配分支 bc 失败后,引擎不会回溯到分组内尝试匹配分支 b。
- 因此,导致整体 匹配失败。
- 示例对比:
public static void main(String[] args) {
String text1 = "abcc";
String text2 = "abc";
// 普通分组正则
Pattern patternNormal = Pattern.compile("a(bc|b)c");
// 原子分组正则
Pattern patternAtomic = Pattern.compile("a(?>bc|b)c");
// 正则: a(bc|b)c | 文本: abcc | 结果: 成功
testMatch(patternNormal, text1);
// 正则: a(?>bc|b)c | 文本: abcc | 结果: 成功
testMatch(patternAtomic, text1);
// 正则: a(?>bc|b)c | 文本: abcc | 结果: 成功
testMatch(patternNormal, text2);
// 正则: a(?>bc|b)c | 文本: abcc | 结果: 成功
testMatch(patternAtomic, text2);
}
private static void testMatch(Pattern pattern, String text) {
Matcher matcher = pattern.matcher(text);
System.out.println("正则: " + pattern.pattern() + " | 文本: " + text +
" | 结果: " + (matcher.matches() ? "成功" : "失败"));
}
五、零宽断言(Lookaround Assertions)
1、概念
- 零宽断言:
- 是正则表达式中用于 匹配位置 的机制。
- 特点:
- 1、不消耗字符:仅检查某个位置是否满足条件,不占用匹配结果。
- 2、零宽度:断言本身不匹配任何实际字符,只定义 约束条件。
- 3、无捕获:不会生成分组或占用分组索引。
2、分类
- 零宽断言:分为 四种类型,按方向和逻辑组合分类。
类型 | 语法 | 作用描述 | 示例 |
---|---|---|---|
正向肯定预查 | (?=pattern) | 右侧必须满足 pattern | Windows(?=95|98) 匹配后面跟着 95 或 98 的 Windows |
正向否定预查 | (?!pattern) | 右侧必须不满足 pattern | Windows(?!95|98) 匹配后面不跟着 95 或 98 的 Windows |
反向肯定预查 | (?<=pattern) | 左侧必须满足 pattern | (?<=95|98)Windows 匹配前面是 95 或 98 的 Windows |
反向否定预查 | (?<!pattern) | 左侧必须不满足 pattern | (?<!95|98)Windows 匹配前面不是 95 或 98 的 Windows |
- 正向肯定预查 示例:
String content = "hello希望教育,希望工程,树理希望小学";
// 只匹配后边跟着<是> 教育 或 小学 的 希望
String regStr = "希望(?=教育|小学)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
/*
找到:希望
找到:希望
*/
while (matcher.find()){
System.out.println("找到:" + matcher.group());
}
- 正向否定预查 示例:
String content = "hello希望教育,希望工程,树理希望小学";
// 只匹配后边跟着<不是> 教育 或 小学 的 希望
String regStr = "希望(?!教育|小学)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
/*
找到:希望
*/
while (matcher.find()){
System.out.println("找到:" + matcher.group());
}
六、量词 的 贪婪模式 与 非贪婪模式
- 量词 描述了一个模式吸收输入文本的方式:
量词(贪婪型) | 勉强型 | 占有型 | 说明 |
---|---|---|---|
X* | X*? | X*+ | 匹配 0 个或多个 X,等价于 {0,}X |
X+ | X+? | X++ | 匹配 1 个或多个 X,等价于 {1,}X |
X? | X?? | X?+ | 匹配 0 个或 1 个 X,等价于 {0,1}X |
X{n} | X{n}? | X{n}+ | 精确匹配 n 个 X |
X{n,} | X{n,}? | X{n,}+ | 至少匹配 n 个 X |
X{0,n} | X{0,n}? | X{0,n}+ | 匹配最多 n 个 X |
X{n,m} | X{n,m}? | X{n,m}+ | 匹配 n 到 m 个 X(包含: n 次 和 m 次) |
1、贪婪型(Greedy)-- 允许回溯
- 贪婪型:量词 的默认行为,适合需要最长匹配的场景。
- 行为:先吞掉所有 可能的字符,若后续匹配失败,则逐步释放字符进行回溯。
- 示例:
public static void main(String[] args) {
String text = "xfooxxxxxxfoo";
// 贪婪型
Pattern pattern = Pattern.compile(".*foo");
Matcher matcher = pattern.matcher(text);
// 输出整个字符串:xfooxxxxxxfoo
while (matcher.find()) {
System.out.println(matcher.group());
}
}
- 解析:.* 吞下全部字符,后续 foo 无法匹配,逐步回退至最后一个 foo 位置完成匹配。
2、勉强型(Reluctant)-- 允许回溯
- 勉强型(Reluctant)也叫: 懒惰的、最少匹配的、非贪婪的、不贪婪的。
- 用问号来指定,这个量词匹配满足模式所需的最少字符数。
- 勉强型:量词 通过 ? 触发,适合需要最短匹配的场景。
- 行为:从最少字符开始匹配,若后续匹配失败,则逐步扩大匹配范围。
- 示例:
public static void main(String[] args) {
String text = "xfooxxxxxxfoo";
// 勉强型
Pattern pattern = Pattern.compile(".*?foo");
Matcher matcher = pattern.matcher(text);
// 输出:
// xfoo
// xxxxxxfoo
while (matcher.find()) {
System.out.println(matcher.group());
}
}
- 解析: .*? 先匹配字符串,后续 foo 匹配失败后逐步扩展,最终匹配到两个结果。
3、占有型(Possessive)-- 禁止回溯
- 这种类型的量词只有在 Java 语言中才可用(在其它语言中不可用)。
- 占有型:量词 通过 + 触发,适合性能敏感且匹配结果确定的场景。
- 行为:吞掉所有可能的字符,且不释放已匹配的字符(不回溯)。
- 示例:
public static void main(String[] args) {
String text = "xfooxxxxxxfoo";
// 占有型
Pattern pattern = Pattern.compile(".*+foo");
Matcher matcher = pattern.matcher(text);
// 输出 false
System.out.println(matcher.find());
}
- 解析:.*+吞下整个字符串,无剩余字符匹配 foo ,且不回溯导致匹配失败。
七、Java 中关于正则表达式的两个类:
1、Pattern 类
- Pattern 对象:表示编译后的正则表达式。
2、Matcher 类 – 代表一个匹配工具类
- 查询
- find():查找下一个匹配正则表达式的字符。
- group():取出上一次与正则表达式的字符串。
- matches():对整个字符串进行匹配,只有整个字符串都匹配了才返回 true 。
- lookingAt():尝试将从区域开头开始的输入序列与该模式匹配。
- 索引方法
- start():返回以前匹配的初始索引。
- end():返回最后匹配字符之后的偏移量。
- 替换方法
- replaceAll(String replacement):
- 替换模式与给定替换字符串相匹配的输入序列的每个子序列。
- replaceFirst(String replacement) :
- 替换模式与给定替换字符串匹配的输入序列的第一个子序列。