检查字符串是否为int,long,float,boolean或double

时间:2020-05-02 21:25:55

标签: scala

我想检查一个字符串是int,long,float,double还是boolean。

例如,“ 1”应为int,“ 1.22”应为float,而“ 1.5555555”应为double。

这是我所管理的最好的事情

case item: String =>

        if (item.toInt.toString.equals(item)) {
          arrayType = Int.getClass
          ByteBuffer.allocate(4 * array.length)
        }
        else if (item.toLong.toString.equals(item)) {
          arrayType = Long.getClass
          ByteBuffer.allocate(8 * array.length)
        }
        else if (item.toFloat.toString.equals(item)) {
          arrayType = Float.getClass
          ByteBuffer.allocate(4 * array.length)
        }
        else if (item.toDouble.toString.equals(item)) {
          arrayType = Double.getClass
          ByteBuffer.allocate(8 * array.length)
        }
        else if (item.toBoolean.toString.equals(item)) {
          arrayType = Boolean.getClass
          ByteBuffer.allocate(array.length)
        }

        else throw new UnsupportedOperationException("Type not supported: " + item.getClass)

2 个答案:

答案 0 :(得分:4)

我看不到所发布的代码如何工作。如果item"true",那么.toInt将抛出并且永远不会进行.toBoolean测试。

我很想使用RegEx进行初始隔离,然后让BigDecimal进行数字解析。

val isBool = "(?i)(?:true|false)".r
val isNum = raw"\d*\.?\d+".r

item match {
  case isBool() => ...
  case isNum() =>
    val bd = BigDecimal(item)
    if      (bd.isValidInt)      ...
    else if (bd.isValidLong)     ...
    else if (bd.isDecimalFloat)  ...
    else if (bd.isDecimalDouble) ...
    else //too big to fit?
  case _ => //report bad item
}

答案 1 :(得分:1)

上一个答案将起作用,尽管它不能捕获所有情况。例如,后缀为fd的数字可以解析为Double或Float,某些字符串(如“ Infinity”或“ -Infinity”)也可以解析。例如,"12.1234567893901f".toFloat -> 12.123457"NaN".toFloat -> NaN。科学级或"E" notation也会解析为浮点数/双打(如果需要,则变为±Infinity)。

  • item.getClass在上一行中将始终为String,因此“ Type not support”错误消息可能会误导您,并且您可能更喜欢带有显示以下内容的消息的IllegalArgumentException {1}},而不是item
  • 对于item.getClass可以成功解析但“未简化”的值s.toXXX.toString.equals(s)而言,检查s不起作用。一种情况是一串长数字:"61234817390131412313458".toDouble.toString = "6.123481739013142E22"。其他“未简化”的值也是如此,例如"+0".toFloat.toString = "0.0"
  • 如评论和以前的答案中所述,每个toXXX方法都可能引发错误,因此,要尝试所有方法,可以将它们包装在Try中。 find的{​​{1}}方法将停止并返回产生List的第一个元素为isSuccess
  • 如果true没有引发错误,则s.toFloat不会引发错误,反之亦然。两者应该一起成功或失败。因此,需要做进一步的检查来确定哪一个更合适(但是s.toDouble可能如上所述太具体了)。
    • 某些(非常正或负)值在解析为浮点数时变为toString.equals,但不是两倍。如果将输入强制进入±Infinity以进行浮点而不是Infinity,那么您可能更喜欢Double。如果两种类型的输入都解析为Double,则选择两种类型。
    • Infinity相比,Float的输入过小将被迫更早归零。

以下是可能的函数定义的概述:

Double