正则表达式常见规则
1. 基础字符匹配
| 字符 | 描述 | 示例 | 匹配 |
|---|---|---|---|
. | 匹配任意单个字符(除换行符) | a.c | abc, a&c, a1c |
[...] | 字符集合,匹配方括号内任意字符 | [abc] | a, b, c |
[^...] | 否定字符集,匹配不在方括号内的字符 | [^abc] | d, e, 1, @ |
\d | 数字字符 | \d | 0-9 |
\D | 非数字字符 | \D | a, A, @, 空格 |
\w | 单词字符(字母、数字、下划线) | \w | a-z, A-Z, 0-9, _ |
\W | 非单词字符 | \W | @, !, 空格 |
\s | 空白字符 | \s | 空格, \t, \n |
\S | 非空白字符 | \S | a, 1, @ |
2. 定位符
| 字符 | 描述 | 示例 | 匹配 |
|---|---|---|---|
^ | 匹配字符串开头 | ^abc | "abc123"中的abc |
$ | 匹配字符串结尾 | abc$ | "123abc"中的abc |
\b | 单词边界 | \bcat\b | "cat"(不匹配"category") |
\B | 非单词边界 | \Bcat\B | "education"中的cat |
3. 量词(重复次数)
| 字符 | 描述 | 示例 | 匹配 |
|---|---|---|---|
* | 0次或多次 | ab*c | ac, abc, abbc |
+ | 1次或多次 | ab+c | abc, abbc(不匹配ac) |
? | 0次或1次 | ab?c | ac, abc |
{n} | 正好n次 | a{3} | aaa |
{n,} | 至少n次 | a{2,} | aa, aaa, aaaa |
{n,m} | n到m次 | a{2,4} | aa, aaa, aaaa |
4. 分组与捕获
| 语法 | 描述 | 示例 | ||
|---|---|---|---|---|
() | 捕获分组 | (ab)+ 匹配ab, abab | ||
(?:) | 非捕获分组 | (?:ab)+ | ||
| ` | ` | 或操作 | `cat | dog` 匹配cat或dog |
5. 转义字符
需要转义的特殊字符:. * + ? ^ $ { } ( ) [ ] | \
\. 匹配点号
\* 匹配星号
\\ 匹配反斜杠
6. 字符类简写
| 简写 | 等效写法 | 描述 |
|---|---|---|
. | [^\n\r] | 除换行符外的任意字符 |
\d | [0-9] | 数字 |
\D | [^0-9] | 非数字 |
\w | [a-zA-Z0-9_] | 单词字符 |
\W | [^a-zA-Z0-9_] | 非单词字符 |
\s | [ \t\n\r\f\v] | 空白字符 |
\S | [^ \t\n\r\f\v] | 非空白字符 |
7. 预定义字符集
| 字符集 | 描述 | 示例 |
|---|---|---|
[a-z] | 小写字母 | a-z |
[A-Z] | 大写字母 | A-Z |
[0-9] | 数字 | 0-9 |
[a-zA-Z] | 所有字母 | |
[0-9a-fA-F] | 十六进制数字 |
8. 贪婪与非贪婪匹配
| 模式 | 描述 | 示例(字符串:" test ") |
|---|---|---|
| 贪婪 | 尽可能多地匹配 | <.*> 匹配整个字符串 |
| 非贪婪 | 尽可能少地匹配 | <.*?> 匹配<div>和</div> |
添加 ? 使量词变为非贪婪:
*?- 0次或多次,非贪婪+?- 1次或多次,非贪婪??- 0次或1次,非贪婪{n,}?- 至少n次,非贪婪
9. 常见模式示例
邮箱验证
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
手机号(中国)
^1(?:3\d|4[5-9]|5[0-9]|6[2567]|7[0-8]|8[0-9]|9[0-9])\d{8}$
URL
https?://[^\s]+
身份证号(18位)
^\d{17}[\dXx]$
日期(YYYY-MM-DD)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
强密码(8-20位,包含大小写字母和数字)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,20}$
10. 在Scala中的使用技巧
// 1. 创建正则表达式
val regex = """\d{3}-\d{8}""".r // 使用三重引号避免转义
// 2. 查找所有匹配
val text = "电话:010-12345678,另一个:021-87654321"
val phones = regex.findAllIn(text).toList
// 3. 提取分组
val datePattern = """(\d{4})-(\d{2})-(\d{2})""".r
"2024-01-15" match {
case datePattern(year, month, day) =>
println(s"$year年$month月$day日")
}
// 4. 替换
val result = "a b c".replaceAll("\\s", ",") // "a,b,c"
// 5. 分割
val parts = "apple,banana,orange".split(",")
11. 实用小贴士
-
测试工具:使用在线正则表达式测试器(如regex101.com)
-
性能:避免嵌套量词和回溯
-
可读性:复杂正则表达式添加注释
(?x) # 启用注释模式 ^ # 字符串开始 \d{3}-\d{4} # 电话号码格式 $ # 字符串结束 -
调试:从简单开始,逐步添加复杂度