快速转换为双精度十进制格式的字符串而不知道这种格式是什么的快速方法

时间:2019-03-28 17:31:23

标签: java kotlin

我有Kotlin语言的代码:

val stringDecimalvalue = ... // can come as '#,###.##' or '#.###,##' and the two are valid

我要以此Double创建一个String

var monetaryValue = Double(stringDecimalvalue)

如果该值采用#,###。## 格式,则会引发NumberFormatException,然后在格式化之前我需要知道此模式。

有一种方法,我不需要滚动整个字符串或使用匹配的正则表达式? (或者也许是轻量级的正则表达式方法)

谢谢!

2 个答案:

答案 0 :(得分:2)

对我来说,最简单的方法似乎是找到,.的最后一个外观,并在此之前删除..的所有外观,那么您应该能够使用Double::parseString

答案 1 :(得分:0)

首先,我需要说的是,没有显式格式的通用提议函数的方法是没有意义的,因为像@gidds和@DodgyCodeException注释一样,它容易含糊。

因此,我解决了使用regex来匹配逗号分隔的小数点分隔符的问题  [0-9]+(,[0-9]{3})*\\.[0-9]{2}和倒写大小写[0-9]+(\\.[0-9]{3})*,[0-9]{2}(逗号分隔,按点分组)。然后清除逗号并替换点,以获取要解析为Double

的无分组点十进制格式

我这样做是extension function

const val NOTHING = ""
const val COMMA = ","
const val POINT = "."

val commaGrouped = "[0-9]+(,[0-9]{3})*\\.[0-9]{2}".toRegex()
val pointGrouped = "[0-9]+(\\.[0-9]{3})*,[0-9]{2}".toRegex()

fun String.commaCleaned() = replace(COMMA, NOTHING)

fun String.pointCleaned() = replace(POINT, NOTHING)

fun String.commaToPoint() = replace(COMMA, POINT)

fun String.pointToComma() = replace(POINT, COMMA)


fun String.toDouble() =
    when {
        commaGrouped matches this -> Double(commaCleaned())
        pointGrouped matches this -> Double(pointCleaned().commaToPoint())
        else -> throw IllegalArgumentException(
            "the value ${this} can't be converted to ${Double::class.java} " +
                "have match ${commaGrouped.pattern} " +
                "or ${pointGrouped.pattern}")
    }

意识到整数格式或两位以上的十进制精度将不匹配创建Double,这也是我想要的。