Scala之提取器,提取可变长度参数及正则表达式

1、需求

给定一个字符串,如果它同时满足如下条件返回:满足,否则返回:不满足

  • 是有效的的Email地址
  • 用户名是tom
  • 域名后缀是com

举例:
输入:tom@sun.com
输出:满足

输入:tom@java.sun.com
输出:满足

输入:peter@java.sun.com
输出:不满足

输入:tom@acm.org
输出:不满足

输入:tom acm.org
输出:不满足

2、传统实现

3、使用Scala提取器特性实现
//Email.scala
object Email {
  def unapply(str: String): Option[(String, String)] = {
    val parts = str split "@"
    if (parts.length == 2) Some(parts(0), parts(1)) else None
  }
}
//Domain.scala
object Domain {
  def unapplySeq(whole: String): Option[Seq[String]] =
    Some(whole.split("\\.").reverse)

  def isTomDotCom(s: String): Unit = s match{
    case Email("tom", Domain("com", _*)) => println("满足")
    case _ => println("不满足")
  }

  def main(args: Array[String]): Unit = {
    val s = "tom@sun.com"
    isTomDotCom(s)

    val s1 = "tom@java.sun.com"
    isTomDotCom(s1)

    val s2 = "peter@java.sun.com"
    isTomDotCom(s2)

    val s3 = "tom@acm.org"
    isTomDotCom(s3)

    val s4 = "tom acm.org"
    isTomDotCom(s4)
  }
}

注意:域名可能由两部分组成,也可能是三部分或更多,即是“变长”的。使用了unapplySeq方法。

4、需求2(和上面的需求没有联系)

给定一个字符串,如果它是有效的Email地址,返回用户名、域名中的顶级域名、除顶级域名外的子域名,否则返回无效或抛出异常。

举例:
输入:tom@support.epfl.ch
输出:
tom
ch
epfl, support

输入:liudehua@gmail.com
输出:
liudehua
com
gmail

输入:liudehua gmail.com
输出:无效或抛出异常

5、传统实现

6、使用Scala提取器特性实现
//ExpandedEMail.scala
object ExpandedEMail {
  def unapplySeq(email: String): Option[(String, Seq[String])] = {
    val parts = email split "@"
    if (parts.length == 2)
      Some(parts(0), parts(1).split("\\.").reverse)
    else
      None
  }

  def main(args: Array[String]): Unit = {
    var s = "tom@support.epfl.ch"
    val ExpandedEMail(name, topDom, subDoms @ _*) = s
    println(name)
    println(topDom)
    println(subDoms)

    println("换一种写法")

    s match {
      case ExpandedEMail(name, topDom, subDoms @ _*) => {
        println(name)
        println(topDom)
        println(subDoms)
      }
      case _ => println("无效")
    }

    var s2 = "liudehua@gmail.com"
    val ExpandedEMail(name2, topDom2, subDoms2 @ _*) = s2
    println(name2)
    println(topDom2)
    println(subDoms2)

    var s3 = "liudehua gmail.com"
    s3 match {
      case ExpandedEMail(name, topDom, subDoms @ _*) => {
        println(name)
        println(topDom)
        println(subDoms)
      }
      case _ => println("无效")
    }

    // 抛出异常:scala.MatchError
    val ExpandedEMail(name3, topDom3, subDoms3 @ _*) = s3
  }
}
7、需求3(和上面的需求没有联系)

给定一个有正负号的实数,找出正负号、整数部分、小数部分。
举例:
输入:-1.23
输出:
负号,即-
1
.23

8、传统实现

9、使用Scala正则表达式提取器特性实现
//Decimal.scala
object Decimal {
  def main(args: Array[String]): Unit = {
    val Decimal = """(-)?(\d+)(\.\d*)?""".r

    val Decimal(sign, integerPart, decimalPart) = "1.0"
    println(sign)
    println(integerPart)
    println(decimalPart)

    val Decimal(sign2, integerPart2, decimalPart2) = "-1.23"
    println(sign2)
    println(integerPart2)
    println(decimalPart2)
  }
}

注意:val Decimal(…)并不是声明一个名称是Decimal的变量,而是使用Decimal正则表达式里的“分组功能”,为括号内的若干变量赋值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值