How to find if a Scala String is parseable as a Double or not?

Suppose that I have a string in scala and I want to try to parse a double out of it.

I know that, I can just call toDouble and then catch the java num format exception if this fails, but is there a cleaner way to do this? For example if there was a parseDouble function that returned Option[Double] this would qualify.

I don't want to put this in my own code if it already exists in the standard library and I am just looking for it in the wrong place.

Thanks for any help you can provide.


For Scala 2.13+ see Xavier's answer below. Apparently there's a toDoubleOption method now.

For older versions:

def parseDouble(s: String) = try { Some(s.toDouble) } catch { case _ => None }

Fancy version (edit: don't do this except for amusement value; I was a callow youth years ago when I used to write such monstrosities):

case class ParseOp[T](op: String => T)
implicit val popDouble = ParseOp[Double](_.toDouble)
implicit val popInt = ParseOp[Int](_.toInt)
// etc.
def parse[T: ParseOp](s: String) = try { Some(implicitly[ParseOp[T]].op(s)) } 
                                   catch {case _ => None}

scala> parse[Double]("1.23")
res13: Option[Double] = Some(1.23)

scala> parse[Int]("1.23")
res14: Option[Int] = None

scala> parse[Int]("1")
res15: Option[Int] = Some(1)

Scalaz provides an extension method parseDouble on Strings, which gives a value of type Validation[NumberFormatException, Double].

scala> "34.5".parseDouble
res34: scalaz.Validation[NumberFormatException,Double] = Success(34.5)

scala> "34.bad".parseDouble
res35: scalaz.Validation[NumberFormatException,Double] = Failure(java.lang.NumberFormatException: For input string: "34.bad")

You can convert it to Option if so required.

scala> "34.bad".parseDouble.toOption
res36: Option[Double] = None

scala> import scala.util.Try
import scala.util.Try

scala> def parseDouble(s: String): Option[Double] = Try { s.toDouble }.toOption
parseDouble: (s: String)Option[Double]

scala> parseDouble("3.14")
res0: Option[Double] = Some(3.14)

scala> parseDouble("hello")
res1: Option[Double] = None

You could try using util.control.Exception.catching which returns an Either type.

So using the following returns a Left wrapping a NumberFormatException or a Right wrapping a Double

import util.control.Exception._

catching(classOf[NumberFormatException]) either "12.W3".toDouble

Scala 2.13 introduced String::toDoubleOption:

"5.7".toDoubleOption                // Option[Double] = Some(5.7)
"abc".toDoubleOption                // Option[Double] = None
"abc".toDoubleOption.getOrElse(-1d) // Double = -1.0