2015-02-06 77 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 € 

毫無疑問,你真的會提取一個貨幣枚舉和一個數字。