tuxdna
tuxdna

Reputation: 8487

What's wrong with Scala Regex in case match?

I have two regexes doubleRegex and intRegex defined below:

scala> val doubleRegex = """^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$""".r
doubleRegex: scala.util.matching.Regex = ^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$

scala> val intRegex = """^[-+]?[0-9]*$""".r
intRegex: scala.util.matching.Regex = ^[-+]?[0-9]*$

Now I want to match a bunch of strings to detect their types:

scala> List(".01", "11", "1.34").map{ s => 
       s match {
          case intRegex() => "INT"
          case doubleRegex() => "DOUBLE"
          case _ => "NONE"
       }
     }
res5: List[String] = List(NONE, INT, NONE)

Why does it not print List(DOUBLE, INT, DOUBLE) ?

Upvotes: 1

Views: 707

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626870

You have a capturing group specified in the doubleRegex, and when executing, you get the capturing groups extracted (and the first capturing group is empty with your examples).

Use doubleRegex(_*) to just check if a string matches without extracting capturing groups:

val doubleRegex = """^[-+]?[0-9]*[.]?[0-9]+([eE][-+]?[0-9]+)?$""".r
val intRegex = """^[-+]?[0-9]*$""".r
print(List(".01", "11", "1.34").map{ s => 
   s match {
      case intRegex(_*) => "INT"
      case doubleRegex(_*) => "DOUBLE"
      case _ => "NONE"
   }
})

See IDEONE demo

Another solution is to change the capturing group into a non-capturing one:

val doubleRegex = """^[-+]?[0-9]*[.]?[0-9]+(?:[eE][-+]?[0-9]+)?$""".r
                                            ^^

Then, you can use your case intRegex() => "INT", and case doubleRegex() => "DOUBLE".

See another IDEONE demo

Upvotes: 2

Related Questions