Scala 正则表达式

71 阅读3分钟

一、笔记概述

本文以 Scala 实现手机号正则匹配为例,详细讲解 Scala 中正则表达式的定义、核心语法及常用使用方法,帮助掌握 Scala 中正则校验的基础流程和关键技巧。

二、核心知识点梳理

1. Scala 正则表达式的定义方式

在 Scala 中,定义正则表达式的简洁方式是:在字符串字面量后添加 .r 方法,该方法会将普通字符串转换为 scala.util.matching.Regex 类型的正则表达式对象,后续可通过该对象调用正则相关方法。

示例代码中的正则定义:

// 定义手机号匹配正则,后缀.r将字符串转为正则对象
val reg = "^1[356789]\\d{9}".r

2. 关键正则语法解析(针对手机号匹配场景)

本次案例用于匹配中国大陆手机号,核心正则语法拆解如下:

正则语法含义说明
^匹配字符串的开头,确保手机号必须以后续规则开头,避免前置无关字符
1固定匹配数字 1,中国大陆手机号首位均为 1
[356789]字符集匹配,匹配中括号内的任意一个字符,对应手机号第二位的合法数字范围
\d匹配任意一个数字(0-9),Scala 字符串中需使用双反斜杠转义,单反斜杠会被识别为转义字符
{9}量词,指定前面的正则规则(此处为\d)必须重复匹配 9 次
完整正则逻辑^1[356789]\d{9} 表示:以 1 开头,第二位为 3/5/6/7/8/9 中的一个,后续跟 9 位数字,整体共 11 位(符合手机号格式)

补充常用量词扩展:

  • {n}:精确匹配 n 次(如\d{11}表示 11 位数字)
  • {n,}:匹配至少 n 次
  • {n,m}:匹配 n 到 m 次
  • *:匹配 0 次或多次(等价于{0,}
  • +:匹配 1 次或多次(等价于{1,}
  • ?:匹配 0 次或 1 次

3. 正则匹配的核心方法:findAllIn

案例中使用 reg.findAllIn(target) 完成匹配操作,该方法的核心特性如下:

  • 功能:在目标字符串中查找所有符合正则表达式规则的子字符串,并非仅匹配整个字符串
  • 返回值:返回一个 Regex.MatchIterator 迭代器对象,可通过遍历获取所有匹配结果
  • 遍历方式:使用 foreach 方法遍历迭代器,输出每个匹配到的子串

示例代码中的调用逻辑:

// 遍历所有匹配结果并打印 
reg.findAllIn(target).foreach(println)

三、案例运行结果分析

1. 案例代码回顾

object test16 {
  def main (args: Array[String]): Unit = {
    // 1.定义正则表达式(匹配11位手机号:1开头,第二位3/5/6/7/8/9,后续9位数字)
    val reg = "^1[356789]\d{9}".r

    // 2.给定目标字符串(长度为13位:1334567898888)
    val target = "1334567898888"

    // 3.查找并输出所有匹配结果
    println("找到的结果是:")
    reg.findAllIn(target).foreach(println)
  }
}

2. 结果说明

运行该代码后,控制台仅输出 “找到的结果是:”,无额外匹配内容打印,原因如下:

  • 正则中的 ^(开头)和 $(结尾)若同时使用,才会强制匹配整个字符串;本案例正则仅包含 ^,表示 “以符合规则的子串开头”,但目标字符串长度为 13 位,超出了正则匹配的 11 位长度
  • 目标字符串1334567898888中,前 11 位13345678988符合正则规则,但由于正则以^开头,仅匹配字符串开头的子串,而后续无其他符合规则的子串,同时因目标字符串整体长度不符,最终无有效匹配结果输出

四、总结

  1. Scala 中通过字符串后缀 .r 可快速定义正则表达式对象,核心语法与 Java 正则兼容,需注意双反斜杠转义特殊字符
  2. findAllIn 方法用于查找目标字符串中所有符合规则的子串,返回迭代器可通过foreach遍历
  3. 正则中的^(开头)、$(结尾)用于限制匹配范围,{n}用于指定精确匹配次数,[ ]用于字符集匹配
  4. 手机号正则匹配的核心规则为^1[356789]\d{9}$(匹配完整 11 位合法手机号),缺少$则仅匹配开头符合规则的子串