1

I found the following regex for matching comma separated numbers or ranges of numbers:

val reg = """^(\d+(-\d+)?)(,\s*(\d+(-\d+)?))*$""".r

While this does match valid strings, I only get one String out of it, instead of a list of strings, each corresponding to one of the separated entries. E.g.

reg.findAllIn("1-2, 3").map(s => s""""$s"""").toList

Gives

List("1-2, 3")

But I want:

List("1-2", "3")

The following comes closer:

val list = "1-2, 3" match {
  case Reg(groups @ _*) => groups
  case _ => Nil
}

list.map(s => s""""$s"""")

But it contains all sorts of 'garbage':

List("1-2", "-2", ", 3", "3", "null")
Community
  • 1
  • 1
0__
  • 66,707
  • 21
  • 171
  • 266

1 Answers1

3

With findAllIn you should not try to match the entire string. It will split by the biggest continuos match it can find. Instead what you need is just a part of your regex:

val reg = """(\d+(-\d+)?)""".r

If you use this with findAllIn it will return what you need.

scala> val x = """(\d+(-\d+)?)""".r
x: scala.util.matching.Regex = (\d+(-\d+)?)

scala> x.findAllIn("1-2, 3").toList
res0: List[String] = List(1-2, 3)
Harshal Pandya
  • 1,622
  • 1
  • 15
  • 17
  • Thanks, that's one step ahead. But now it just swallows everything that it doesn't understand, e.g. `"1-2, schoko 3"` produces the same result, but should be rejected. – 0__ May 13 '13 at 23:43
  • So in this case you want to reject the entire string or skip this part and move on? – Harshal Pandya May 13 '13 at 23:48
  • I want to reject the entire string... but... I'm using this with a `JFormattedTextField`, and with the `COMMIT_OR_REVERT` policy, it automatically throws away the garbage, so I think I kind of like that behaviour. (I'm still curious how one can write the matcher to refuse ill formatted strings). – 0__ May 13 '13 at 23:49
  • in that case you can do this in two steps. first validate full string match using the original regex you posted and then extract using what I suggested. – Harshal Pandya May 14 '13 at 00:05