Java 正则表达式
正则表达式概述
正则表达式(Regular Expression)是一种用于匹配字符串模式的工具,它使用特定的语法规则来描述字符串的结构。Java中的正则表达式由java.util.regex包提供支持,主要包括Pattern类和Matcher类。
正则表达式的用途
- 字符串匹配:检查一个字符串是否符合特定的格式要求,如邮箱、手机号、身份证号等。
- 字符串查找:在一个字符串中查找符合特定模式的子串。
- 字符串替换:将一个字符串中符合特定模式的子串替换为其他内容。
- 字符串分割:根据特定的分隔符将一个字符串分割成多个子串。
正则表达式的特点
- 灵活性:可以使用简单的语法描述复杂的字符串模式。
- 强大性:支持多种匹配方式,如贪婪匹配、非贪婪匹配、正向预查、反向预查等。
- 效率高:使用编译后的正则表达式可以提高匹配效率。
正则表达式语法
基本语法
字符匹配
| 语法 | 描述 | 示例 |
|---|---|---|
. | 匹配任意单个字符(除了换行符) | a.c 匹配 abc、adc 等 |
\d | 匹配任意数字(等价于 [0-9]) | \d+ 匹配 123、456 等 |
\D | 匹配任意非数字(等价于 [^0-9]) | \D+ 匹配 abc、!@# 等 |
\w | 匹配任意字母、数字或下划线(等价于 [a-zA-Z0-9_]) | \w+ 匹配 hello、user123 等 |
\W | 匹配任意非字母、数字或下划线(等价于 [^a-zA-Z0-9_]) | \W+ 匹配 !@#、$%^ 等 |
\s | 匹配任意空白字符(空格、制表符、换行符等) | \s+ 匹配多个空白字符 |
\S | 匹配任意非空白字符 | \S+ 匹配多个非空白字符 |
字符类
| 语法 | 描述 | 示例 |
|---|---|---|
[abc] | 匹配方括号中的任意一个字符 | [abc] 匹配 a、b 或 c |
[^abc] | 匹配除了方括号中的字符以外的任意字符 | [^abc] 匹配除了 a、b、c 以外的任意字符 |
[a-z] | 匹配小写字母 | [a-z]+ 匹配 hello、world 等 |
[A-Z] | 匹配大写字母 | [A-Z]+ 匹配 HELLO、WORLD 等 |
[0-9] | 匹配数字 | [0-9]+ 匹配 123、456 等 |
[a-zA-Z0-9] | 匹配字母或数字 | [a-zA-Z0-9]+ 匹配 Hello123、World456 等 |
量词
| 语法 | 描述 | 示例 |
|---|---|---|
* | 匹配前面的字符0次或多次(贪婪匹配) | a* 匹配 ""、a、aa、aaa 等 |
+ | 匹配前面的字符1次或多次(贪婪匹配) | a+ 匹配 a、aa、aaa 等 |
? | 匹配前面的字符0次或1次(贪婪匹配) | a? 匹配 "" 或 a |
{n} | 匹配前面的字符恰好n次 | a{3} 匹配 aaa |
{n,} | 匹配前面的字符至少n次(贪婪匹配) | a{2,} 匹配 aa、aaa、aaaa 等 |
{n,m} | 匹配前面的字符至少n次,最多m次(贪婪匹配) | a{2,4} 匹配 aa、aaa、aaaa |
*? | 匹配前面的字符0次或多次(非贪婪匹配) | a*? 尽可能少地匹配 a |
+? | 匹配前面的字符1次或多次(非贪婪匹配) | a+? 匹配 a |
?? | 匹配前面的字符0次或1次(非贪婪匹配) | a?? 匹配 "" |
{n,}? | 匹配前面的字符至少n次(非贪婪匹配) | a{2,}? 匹配 aa |
{n,m}? | 匹配前面的字符至少n次,最多m次(非贪婪匹配) | a{2,4}? 匹配 aa |
边界匹配
| 语法 | 描述 | 示例 |
|---|---|---|
^ | 匹配字符串的开头 | ^abc 匹配以 abc 开头的字符串 |
$ | 匹配字符串的结尾 | abc$ 匹配以 abc 结尾的字符串 |
\b | 匹配单词边界 | \bword\b 匹配完整的单词 word |
\B | 匹配非单词边界 | \Bword\B 匹配单词内部的 word |
逻辑运算符
| 语法 | 描述 | 示例 |
|---|---|---|
| ` | ` | 或运算,匹配左边或右边的表达式 |
() | 分组,将多个字符作为一个整体处理 | (ab)+ 匹配 ab、abab、ababab 等 |
(?:) | 非捕获分组,不捕获匹配的内容 | (?:ab)+ 匹配 ab、abab 等,但不捕获分组内容 |
(?=) | 正向预查,匹配后面跟着指定内容的位置 | a(?=b) 匹配后面跟着 b 的 a |
(?!=) | 负向预查,匹配后面不跟着指定内容的位置 | a(?!b) 匹配后面不跟着 b 的 a |
转义字符
在正则表达式中,有些字符具有特殊含义,如 .、*、+ 等。如果要匹配这些字符本身,需要使用转义字符 \。
例如,要匹配 . 字符,需要使用 \.。
在Java字符串中,\ 本身也是一个转义字符,因此需要使用两个 \ 来表示一个 \。
例如,要匹配 . 字符,在Java字符串中需要写为 \\.。
Pattern类和Matcher类
Pattern类
Pattern 类是正则表达式的编译表示,用于将正则表达式编译成一个可以被重用的对象。
常用方法
static Pattern compile(String regex):将正则表达式编译成Pattern对象。static Pattern compile(String regex, int flags):将正则表达式编译成Pattern对象,并指定匹配标志。Matcher matcher(CharSequence input):创建一个Matcher对象,用于匹配指定的输入字符串。static boolean matches(String regex, CharSequence input):判断输入字符串是否与正则表达式匹配。String[] split(CharSequence input):根据正则表达式将输入字符串分割成字符串数组。String[] split(CharSequence input, int limit):根据正则表达式将输入字符串分割成字符串数组,并指定分割的最大数量。static String quote(String s):返回指定字符串的字面量模式字符串,用于匹配字符串本身。
匹配标志
| 标志 | 描述 |
|---|---|
Pattern.CASE_INSENSITIVE | 忽略大小写匹配 |
Pattern.MULTILINE | 多行模式,^ 和 $ 匹配每行的开头和结尾 |
Pattern.DOTALL | 点号匹配所有字符,包括换行符 |
Pattern.UNICODE_CASE | 启用Unicode大小写折叠 |
Pattern.CANON_EQ | 启用规范等价匹配 |
Pattern.LITERAL | 启用字面量解析模式 |
Pattern.UNICODE_CHARACTER_CLASS | 启用Unicode字符类 |
Matcher类
Matcher 类用于执行正则表达式的匹配操作,它可以对输入字符串进行多种匹配操作。
常用方法
boolean matches():判断整个输入字符串是否与正则表达式匹配。boolean lookingAt():判断输入字符串的开头是否与正则表达式匹配。boolean find():查找输入字符串中与正则表达式匹配的子串,返回是否找到。boolean find(int start):从指定位置开始查找输入字符串中与正则表达式匹配的子串,返回是否找到。String group():返回上一次匹配的子串。String group(int group):返回上一次匹配的指定分组的子串。int groupCount():返回正则表达式中的分组数量。int start():返回上一次匹配的子串的起始位置。int start(int group):返回上一次匹配的指定分组的子串的起始位置。int end():返回上一次匹配的子串的结束位置(不包括)。int end(int group):返回上一次匹配的指定分组的子串的结束位置(不包括)。String replaceAll(String replacement):将输入字符串中所有与正则表达式匹配的子串替换为指定的字符串。String replaceFirst(String replacement):将输入字符串中第一个与正则表达式匹配的子串替换为指定的字符串。Matcher reset():重置Matcher对象,使其可以重新匹配输入字符串。Matcher reset(CharSequence input):重置Matcher对象,并指定新的输入字符串。
正则表达式的应用场景
数据验证
- 验证邮箱格式
- 验证手机号格式
- 验证身份证号格式
- 验证密码强度
- 验证URL格式
- 验证IP地址格式
数据提取
- 从日志文件中提取关键信息
- 从HTML文档中提取链接
- 从文本中提取日期和时间
- 从字符串中提取数字
数据清洗
- 去除字符串中的空格和换行符
- 替换敏感信息
- 格式化文本
文本处理
- 查找和替换文本
- 分割文本
- 提取文本中的特定模式
正则表达式的最佳实践
1. 编译正则表达式
对于频繁使用的正则表达式,应该将其编译成Pattern对象,以提高匹配效率。
2. 使用合适的匹配模式
根据需要选择合适的匹配模式,如忽略大小写、多行模式等。
3. 避免过度使用正则表达式
对于简单的字符串操作,如查找和替换固定字符串,使用String类的方法可能更高效。
4. 注意正则表达式的性能
复杂的正则表达式可能会导致性能问题,尤其是在处理大量数据时。应该尽量简化正则表达式,避免使用过度复杂的模式。
5. 使用非捕获分组
对于不需要捕获的分组,应该使用非捕获分组 (?:),以提高匹配效率。
6. 测试正则表达式
在使用正则表达式之前,应该充分测试其是否能正确匹配各种情况,包括正常情况和边界情况。
7. 注释正则表达式
对于复杂的正则表达式,应该添加注释,以提高代码的可读性和可维护性。
总结
Java正则表达式是一种强大的字符串处理工具,它可以用于字符串匹配、查找、替换和分割等操作。通过学习正则表达式的语法和API,我们可以编写出高效、灵活的字符串处理代码。
在使用正则表达式时,我们应该注意以下几点:
- 编译正则表达式以提高匹配效率
- 使用合适的匹配模式
- 避免过度使用正则表达式
- 注意正则表达式的性能
- 使用非捕获分组
- 测试正则表达式
- 注释正则表达式
通过掌握Java正则表达式,我们可以更高效地处理字符串,提高代码的质量和可维护性。