1. Overview
In this tutorial, we’ll see a few different solutions to check if a given string is a number using Scala.
2. Using Character.isDigit
Checking if a String is a number is trickier than it sounds. If we’re sure there’s no decimal part, then we can leverage the Char.isDigit method:
scala> val number = "123"
nuval number: String = 123
scala> number.forall(Character.isDigit)
val res0: Boolean = true
scala> val number = "0.5"
val number: String = 0.5
scala> number.forall(Character.isDigit)
val res1: Boolean = false
The Char.isDigit method returns true if the character is a number. Unfortunately, this solution won’t work for numbers with decimal parts, as the separator will make the method return false.
3. Using toDouble Conversion
A more robust solution is to use the String.toDouble or String.toDoubleOption methods. Both try to convert the String to a Double. While the first one throws an exception if it’s not possible to do so, the latter returns an empty Option:
scala> val number = "123"
val number: String = 123
scala> number.toDouble
val res0: Double = 123.0
scala> number.toDoubleOption
val res1: Option[Double] = Some(123.0)
scala> val number = "0.5"
val number: String = 0.5
scala> number.toDouble
val res2: Double = 0.5
scala> number.toDoubleOption
val res3: Option[Double] = Some(0.5)
scala> val number = "123_random"
val number: String = 123_random
scala> number.toDouble
java.lang.NumberFormatException: For input string: "123_random"
scala> number.toDoubleOption
val res5: Option[Double] = None
As we can see, both work for numbers with and without decimal parts. If we are sure that the number will be an integer, we can use String.toInt and String.toIntOption methods.
4. Using Regex
Another possible solution is to use a regex for this problem. While it’s usually not recommended, it may work. Just take into account that the number to be parsed may contain decimal parts, thousands separators. Different parts of the globe use different separators (some use comma before the decimal part, others use dot).
Assuming numbers don’t have the thousands separators, this should do the trick:
scala> val regex = "\\d+\\.?\\d+"
val regex: String = \d+\.?\d+,
scala> val number = "123"
val number: String = 123
scala> number.matches(regex)
val res0: Boolean = true
scala> val number = "0.5"
val number: String = 0.5
scala> number.matches(regex)
val res1: Boolean = true
scala> val number = "42_random"
val number: String = 42_random
scala> number.matches(regex)
val res2: Boolean = false
Once again, we should be cautious when using regexes. Many systems have failed due to exploitation of Regular expression Denial of Service.
5. Conclusion
In this article, we saw how we could find if a given string is a number using the many different tools Scala provides.