andreas andreas - 14 days ago 7
Scala Question

Match case not behaving the same as Regex.findAll

I have a little helper method, which has to normalize some money values. Hence, I wrote some regular expressions, which should detect different ways of representing them. Strangely they only trigger if used with Regex.findAllIn(..), but not if used in a match case statement.

val result = extractAmount("23772.90")

def extractAmount(amountStr: String): BigDecimal = {
val Plain = """^\d+$""".r
val Dot = """^(\d+)\.(\d*)$""".r
val Comma = """^(\d+),(\d*)$""".r
val DotComma = """^(\d+)\.(\d+),(\d*)$""".r
val CommaDot = """^(\d+),(\d+)\.(\d*)$""".r

if (Dot.findAllIn(amountStr).hasNext)
println(Dot.findAllIn(amountStr).next())

amountStr match {
case Plain(value) => new java.math.BigDecimal(value)
case Dot(values) => new BigDecimal(s"${values(0)}.${values(1)}")
case Comma(values) => new BigDecimal(s"${values(0)}.${values(1)}")
case DotComma(values) => new BigDecimal(s"${values(0)}${values(1)}.${values(2)}")
case CommaDot(values) => new BigDecimal(s"${values(0)}${values(1)}.${values(2)}")
case _ => throw new RuntimeException(s"Money amount string -->${amountStr}<-- did not match any pattern.")
}
}


Debugger output hitting Regex.findAllIn(..):
debugger screen shot 1

Debugger output not hitting the match case for Dot(values):
debugger screen shot 2

Also interesting might be following error message in the debugger:
Debugger error message

Using scala version 2.11.8.

I am puzzled, for sure overlooking something obvious. Thankful for a hint.

Answer

Instead of doing e.g.

case Dot(values) => new BigDecimal(s"${values(0)}.${values(1)}")

rewrite the usage of your Regex extractors like this:

case Dot(a, b) => new BigDecimal(s"$a.$b")

The amount of arguments in each extractor must match the amount of groups your regex contains (here: 2). Each argument is just a string that represents the content of one single group.

Comments