如何查找Scala字符串是否可解析为Double?

chu*_*lor 48 scala

假设我在scala中有一个字符串,我想尝试解析它的双重.

我知道,toDouble如果失败,我可以调用然后捕获java num格式异常,但是有更简洁的方法吗?例如,如果有一个parseDouble返回的函数Option[Double]将符合条件.

我不想把它放在我自己的代码中,如果它已经存在于标准库中,我只是在错误的地方寻找它.

感谢您的任何帮助,您可以提供.

Lui*_*hys 53

要不就

def parseDouble(s: String) = try { Some(s.toDouble) } catch { case _ => None }
Run Code Online (Sandbox Code Playgroud)

花式版:

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)
Run Code Online (Sandbox Code Playgroud)

  • 你应该真的抓住`NonFatal(_)`,而不仅仅是`_`. (3认同)
  • 你应该使用`Try`函数.见@Jeff Schwab回答. (2认同)

mis*_*tor 31

Scalaz parseDoubleStrings 上提供了一个扩展方法,它给出了一个类型的值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")
Run Code Online (Sandbox Code Playgroud)

Option如果需要,您可以将其转换为.

scala> "34.bad".parseDouble.toOption
res36: Option[Double] = None
Run Code Online (Sandbox Code Playgroud)


Jef*_*wab 19

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
Run Code Online (Sandbox Code Playgroud)


Don*_*zie 10

你可以尝试使用util.control.Exception.catching哪个返回一个Either类型.

因此,使用以下命令返回左包装NumberFormatException或右包装aDouble

import util.control.Exception._

catching(classOf[NumberFormatException]) either "12.W3".toDouble
Run Code Online (Sandbox Code Playgroud)


Fix*_*int 6

这不仅仅是在Scala中,甚至在基本Java中也是如此.

这是一个没有例外的片段代码,但是:

def parseDouble(s: String)(implicit nf: NumberFormat) = {
    val pp = new ParsePosition(0)
    val d = nf.parse(s, pp)
    if (pp.getErrorIndex == -1) Some(d.doubleValue) else None
}
Run Code Online (Sandbox Code Playgroud)

用法:

implicit val formatter = NumberFormat.getInstance(Locale.ENGLISH)

Console println parseDouble("184.33")
Console println parseDouble("hello, world")
Run Code Online (Sandbox Code Playgroud)


Rex*_*err 6

不幸的是,这不在标准库中.这是我使用的:

class SafeParsePrimitive(s: String) {
  private def nfe[T](t: => T) = {
    try { Some(t) }
    catch { case nfe: NumberFormatException => None }
  }
  def booleanOption = s.toLowerCase match {
    case "yes" | "true" => Some(true)
    case "no" | "false" => Some(false)
    case _ => None
  }
  def byteOption = nfe(s.toByte)
  def doubleOption = nfe(s.toDouble)
  def floatOption = nfe(s.toFloat)
  def hexOption = nfe(java.lang.Integer.valueOf(s,16))
  def hexLongOption = nfe(java.lang.Long.valueOf(s,16))
  def intOption = nfe(s.toInt)
  def longOption = nfe(s.toLong)
  def shortOption = nfe(s.toShort)
}
implicit def string_parses_safely(s: String) = new SafeParsePrimitive(s)
Run Code Online (Sandbox Code Playgroud)


Xav*_*hot 6

Scala 2.13介绍String::toDoubleOption

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