1

I want to check that each element in String is digit. Firstly, I split the String to an Array by a regexp [, ]+ expression and then I try to check each element by forall and isDigit.

object Test extends App {
  val st = "1, 434, 634, 8"

  st.split("[ ,]+") match {
    case arr if !arr.forall(_.forall(_.isDigit)) => println("not an array")
    case arr if arr.isEmpty                      => println("bad delimiter")
    case _                                       => println("success")
  }
}

How can I improve this code and !arr.forall(_.forall(_.isDigit))?

Ricky McMaster
  • 4,289
  • 2
  • 24
  • 23
Vadim
  • 753
  • 8
  • 22

2 Answers2

1

I think it can be simplified while also making it a bit more robust.

val st = "1,434 , 634   , 8"  //a little messier but still valid

st.split(",").forall(" *\\d+ *".r.matches)  //res0: Boolean = true

I'm assuming strings like "1,,,434 , 634 2 , " should fail.

The regex can be put in a variable so that it is compiled only once.

val digits = " *\\d+ *".r
st.split(",").forall(digits.matches)
jwvh
  • 50,871
  • 7
  • 38
  • 64
1

Use matches that requires the string to fully match the pattern:

st.matches("""\d+(?:\s*,\s*\d+)*""")

See the Scala demo and the regex demo.

Details

  • In a triple quoted string literal, there is no need to double escape backslashes that are part of regex escapes
  • Anchors - ^ and $ - are implicit when the pattern is used with .matches
  • The regex means 1+ digits followed with 0 or more repetitions of a comma enclosed with 0 or more whitespaces and then 1+ digits.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Returns **false** for strings like `" 1,2,4"` and `"1,2,4 "`. Not sure if that's desired results or not. – jwvh Nov 14 '19 at 08:18
  • @jwvh It is expected, see the sample input in the question that has no leading/trailing whitespace. Anyway, it can easily be added with `\s*` at the start and end of the pattern – Wiktor Stribiżew Nov 14 '19 at 08:19
  • Just curious: Why make it non-capture? What advantage does the `?:` add? – jwvh Nov 14 '19 at 08:29
  • 1
    @jwvh See [Are non-capturing groups redundant?](https://stackoverflow.com/questions/31500422/are-non-capturing-groups-redundant). In short: the best practice is to only use capturing groups only when you need to access part of the regex match after it occurred. – Wiktor Stribiżew Nov 14 '19 at 08:30