Scala之旅-正则表达式模式和提取器对象(EXTRACTOR OBJECTS)

正则表达式模式

正则表达式是用于查找数据中的模式的字符串。任何字符串都可以使用 .r 方法转换为正则表达式。

import scala.util.matching.Regex
val numberPattern: Regex = "[0-9]".r
numberPattern.findFirstMatchIn("awesomepassword") match {
  case Some(_) => println("Password OK")
  case None => println("Password must contain a number")
}

这里写图片描述
在上面的例子中,numberPattern 是一个 Regex (正则表达式),我们可以用它来确保一个密码中需包含一个数字。

你也可以使用圆括号匹配正则表达式组。

import scala.util.matching.Regex
val keyValPattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r
val input: String =
  """background-color: #A03300;
    |background-image: url(img/header100.png);
    |background-position: top center;
    |background-repeat: repeat-x;
    |background-size: 2160px 108px;
    |margin: 0;
    |height: 108px;
    |width: 100%;""".stripMargin
for (patternMatch <- keyValPattern.findAllMatchIn(input))
  println(s"key: ${patternMatch.group(1)} value: ${patternMatch.group(2)}")

这里写图片描述
这里我们解析出字符串的键和值。每个匹配都有一组子匹配。下面是输出结果:

key: background-color value: #A03300
key: background-image value: url(img
key: background-position value: top center
key: background-repeat value: repeat-x
key: background-size value: 2160px 108px
key: margin value: 0
key: height value: 108px
key: width value: 100

这里写图片描述

提取器对象(EXTRACTOR OBJECTS)

提取器对象是一个含有 unapply 方法的对象。而 apply 方法就像一个带参数并创建对象的构造器,unapply 方法接受一个对象并尝试返回参数。这个最常使用在模式匹配和部分函数中。

import scala.util.Random
object CustomerID {
  def apply(name: String) = s"$name--${Random.nextLong}"
  def unapply(customerID: String): Option[String] = {
    val name = customerID.split("--").head
    if (name.nonEmpty) Some(name) else None
  }
}
val customer1ID = CustomerID("Sukyoung")  // Sukyoung--23098234908
customer1ID match {
  case CustomerID(name) => println(name)  // prints Sukyoung
  case _ => println("Could not extract a CustomerID")
}

这里写图片描述
apply 方法根据 name 创建了 CustomerID 字符串。unapply 方法反过来求 name。当我们调用 CustomerID("Sukyoung") 时,这其实是 CustomerID.apply("Sukyoung") 的缩写形式。当我们调用 case CustomerID(name) => println(name) 时,我们调用的是 unapply 方法。

unapply 方法也可以用于分配一个值。

val customer2ID = CustomerID("Nico")
val CustomerID(name) = customer2ID
println(name)  // prints Nico

这种写法和 val name = CustomerID.unapply(customer2ID).get 是等价的。

如果不匹配,将会抛出一个 scala.MatchError

val CustomerID(name2) = "--asdfasdfasdf"

这里写图片描述
unapply 的返回类型选择如下:

  • 如果仅仅是测试,则返回一个 boolean,例如 case even()
  • 如果返回 T 类型的单个子值,则返回 Option[T]
  • 如果你想返回几个子值 T1,..,Tn,则可以把它们分配在可选择的元组(tuple)中 Option[(T1,...,Tn)]

有时,由于返回的子值数量不固定,我们将会返回一个序列。由于这个原因,你也可以通过 unapplySeq 定义模式来返回 Option[Seq[T]] ,这种机制使用在 case List(x1, ..., xn) 模式中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值