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

导读:本篇文章讲解 Scala之提取器,提取可变长度参数及正则表达式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

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正则表达式里的“分组功能”,为括号内的若干变量赋值。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/17230.html

(0)
小半的头像小半

相关推荐

极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!