Scala中的正则表达式(二)

37 阅读2分钟

正则表达式常见规则

1. 基础字符匹配

字符描述示例匹配
.匹配任意单个字符(除换行符)a.cabc, a&c, a1c
[...]字符集合,匹配方括号内任意字符[abc]a, b, c
[^...]否定字符集,匹配不在方括号内的字符[^abc]d, e, 1, @
\d数字字符\d0-9
\D非数字字符\Da, A, @, 空格
\w单词字符(字母、数字、下划线)\wa-z, A-Z, 0-9, _
\W非单词字符\W@, !, 空格
\s空白字符\s空格, \t, \n
\S非空白字符\Sa, 1, @

2. 定位符

字符描述示例匹配
^匹配字符串开头^abc"abc123"中的abc
$匹配字符串结尾abc$"123abc"中的abc
\b单词边界\bcat\b"cat"(不匹配"category")
\B非单词边界\Bcat\B"education"中的cat

3. 量词(重复次数)

字符描述示例匹配
*0次或多次ab*cac, abc, abbc
+1次或多次ab+cabc, abbc(不匹配ac)
?0次或1次ab?cac, 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)+
``或操作`catdog` 匹配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. 实用小贴士

  1. 测试工具:使用在线正则表达式测试器(如regex101.com)

  2. 性能:避免嵌套量词和回溯

  3. 可读性:复杂正则表达式添加注释

    (?x)           # 启用注释模式
    ^              # 字符串开始
    \d{3}-\d{4}    # 电话号码格式
    $              # 字符串结束
    
  4. 调试:从简单开始,逐步添加复杂度