将Scala Regex.unapplySeq()转换为元组

时间:2015-02-24 16:54:35

标签: regex scala

有没有人知道在没有传递每个值的情况下是否有一个简短的方法:

case class Person(title: String, first: String, last: String)

val name = """(Mr|Mrs|Ms)\. ([A-Z][a-z]+) ([A-Z][a-z]+)""".r
val name(title, first, last) = "Mr. James Stevens"

Person.tupled((title, first, last))

我正在寻找一种方法来将正则表达式的结果作为元组直接传递给Person.tupled()。

谢谢,Torben

2 个答案:

答案 0 :(得分:0)

这不是完全可能的,因为unapplySeq会返回List。有关推理和一些可能性,请参阅this SO question on list to tuple

最佳解决方案可能是模式匹配

Person.tupled(nameString match {
  case name(first, middle, last) => (first, middle, last)
})

答案 1 :(得分:0)

您可以为此编写自己的提取器:

object NameRegex {
    private val name = """(Mr|Mrs|Ms)\. ([A-Z][a-z]+) ([A-Z][a-z]+)""".r
    def unapply(x: String) = name.unapplySeq(x).collect {
        case(List(title, first, last)) => (title, first, last)
    }
}

然后你可以做

val NameRegex(tuple) = "Mr. Charles Darwin"
Person.tupled(tuple)

或者:

"Mr. Ben Reich" match {
    case NameRegex(tuple) => Person.tupled(tuple)
}

或者您可以使NameRegex对象与Person对象匹配:

object NameRegex {
    private val name = """(Mr|Mrs|Ms)\. ([A-Z][a-z]+) ([A-Z][a-z]+)""".r
    def unapply(x: String) = name.unapplySeq(x).collect {
        case(List(title, first, last)) => Person(title, first, last)
    }
}

那么你可以一步提取个人案例类:

val NameRegex(p) = "Mr. Barack Obama" //p is Person("Mr", "Barack", "Obama")
val NameRegex(p@Person(title, first, last)) = "Mr. Barack Obama"