我有这段 kotlin 语言的代码:
val stringDecimalvalue = ... // can come as '#,###.##' or '#.###,##' and the two are valid
我想用这个String
创建一个Double
var monetaryValue = Double(stringDecimalvalue)
如果值为 #,###.## 格式,则会引发NumberFormatException
,那么我需要在格式化之前知道这种模式。
有一种方法我不需要滚动整个字符串或应用带有匹配的正则表达式?(或者也许是一种轻正则表达式方法(
谢谢!
最简单的方法似乎是找到,
或.
的最后一次出现并在此之前删除.
和.
的所有外观,那么您应该能够使用Double::parseString
首先,我需要说,没有显式格式的一般用途提议函数的方法没有意义,因为就像@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
,这也是我想要的。