使用正则表达式处理字符串

字符串中正则表达式模式匹配

通过在String上调用.r方法来创建一个scala.util.matching.Regex对象,然后在findFirstIn中使用该模式来查找一个匹配,在findAllIn中使用该模式来查找所有的匹配。

    // 使用正则表达式匹配
    val numPattern = "[0-9]+".r
    val address = "123 Main Street Suite 101"

    val match1 = numPattern.findFirstIn(address)    // 返回的是一个Option[String]
    println(match1.get)      // 123

    val matches = numPattern.findAllIn(address)     // 返回的是一个Option[String]
    matches.foreach(println)  // 123  101
    
    // 将匹配结果转为Array数组: toArray,toList,toSeq,toVector
    val matches2 = numPattern.findAllIn(address).toArray   // Array(123, 101)
    
    // 另一种方法
    import scala.util.matching.Regex

    val numPattern3 = new Regex("[0-9]+")
    val address3 = "123 Main Street Suite 101"
    val match3 = numPattern.findFirstIn(address)
    println(match3)         // Some(123)
    println(match3.get)      // 123
    
    // 处理返回的值:Option/Some/None
    val result5 = numPattern3.findFirstIn(address3).getOrElse("no match")
    println(result5)      // 123

    // 因为一个Option是零个或一个元素的集合
    numPattern3.findFirstIn(address3).foreach { e => println(e)}     // 123
    numPattern3.findFirstIn(address3).foreach(println)             // 123
    // 还可以这样处理:使用模式匹配
    match1 match {
      case Some(s) => println(s"发现: $s")           // 123
      case None => println("什么也没找到")
    }

提取与正则表达式相匹配的部分(一个或多个)

提取与正则表达式相匹配的部分(一个或多个),使用group。

val pattern9 = "([0-9]+) ([A-Za-z]+)".r

下面的代码从给定的字符串提取数值字段和字母字段作为两个变量: count和fruit。

val pattern9(count, fruit) = "100 Bananas"
println(count,fruit)

val datePattern = """(\d\d\d\d)-(\d\d)-(\d\d)""".r
val dates = "历史上重要的时刻: 2004-01-20, 1958-09-05, 2010-10-06, 2011-07-15"
val firstDate = datePattern findFirstIn dates getOrElse "No date found."
val firstYear = for (m <- datePattern findFirstMatchIn dates) yield m group 1

字符串拆分

可以使用split方法对字符串按指定的分割符进行分割。请看下面的示例代码:

"hello world".split(" ")
"hello world".split(" ").foreach(println)
    
val s33 = "鸡蛋, 牛奶, 面包, 可口 可乐"
s33.split(",")     // 返回一个数组
s33.split(",").map(_.trim).foreach(println)
    
// 基于正则表达式拆分(按逗号或空格分割)
"hello world,this is Al".split(",|\\s+").foreach(println)

字符串替换

在字符串上调用replaceAll方法执行一个替换,返回一个新的字符串。

    // 字符串替换
    val address6 = "123 Main Street".replaceAll("[0-9]", "x")
    println(address6)                              // xxx Main Street

    // 也可以先定义一个正则表达式,然后执行replaceAllIn方法
    val regex = "[0-9]".r
    val newAddress = regex.replaceAllIn("123 Main Street", "x")
    println(newAddress)                           // xxx Main Street

    // 只替换第一个匹配到的
    val result7 = "123".replaceFirst("[0-9]", "x")
    println(result7)				  // x23

    // 还可以在Regex上调用replaceFirstIn
    val regex8 = "H".r
    val result8 = regex8.replaceFirstIn("Hello Hi world", "J")
    println(result8)                             // Jello Hi world

《Spark原理深入与编程实战》