2015-02-06 44 views
0

如何进行模式匹配以匹配所有元素直到最后一个元素?Scala:字符串开头的模式匹配零或更多

例如,假设我有这样的unapplySeq:

object MyObject { 
    def unapplySeq(money: String): Option[List[Char]] = { 
    val amount = money.trim.toList 
    if (amount.isEmpty) None 
    else 
     Some(amount) 
    } 
} 

我尝试以下匹配:

"12.15 €" match { 
    case MyObject('$' , last @ _*) => s"${last.mkString} dollars" 

    // this is wrong 
    case MyObject(first @ _*, '€') => s"${last.mkString} euro" 

    case _ => "Unknown format" 
} 

我能为美国达在那里我通过例如120.10 $做到这一点,但我如何重写第二种情况以匹配符号在最后的欧元字符串?

回答

2

这将是非常简单的正则表达式与

def currency(s: String) { 
    val dollar = """\$(.+)""".r 
    val euro = """(.+)€""".r 
    s match { 
    case dollar(amt) => println(amt + " dollars") 
    case euro(amt) => println(amt + " euros") 
    case _ => println("unknown currency") 
    } 
} 

scala> currency("$1346.00") 
1346.00 dollars 

scala> currency("1346.00€") 
1346.00 euros 
+0

谢谢。我想过正则表达式,可能会朝着这个方向发展。然而,似乎任何人认为实施以前的方法会被鸟或松鼠等分散注意力,并且没有考虑实施其他常见变化。我试图确保我没有错过我发布的非正则表达式方法。 – 2015-02-06 23:20:10

1

可能,正则表达式是大材小用来表达 “startsWith” 和 “的endsWith”。

一个简单的提取器可以完成这项工作,但是将字符串转换为字符串列表是一个缺点。

scala> object Currency { def unapply(s: String): Option[(Char, String)] = 
    | if (s.head == '$') Some('$',s.tail) 
    | else if (s.last == '€') Some('€',s.init) else None } 
defined object Currency 

scala> def currency(s: String) = s match { case Currency(c, amt) => s"$amt of $c" case _ => "unknown" } 
currency: (s: String)String 

scala> currency("$120.10") 
res2: String = 120.10 of $ 

scala> currency("1346.00€") 
res3: String = 1346.00 of € 

毫无疑问,你真的会提取一个货币枚举和一个数字。