You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让标准Kotlin与Android Kotlin解析畸形数字结果一致?

解决标准Kotlin与Android Kotlin中NumberFormat解析畸形数字的一致性问题

问题背景

使用java.text.NumberFormat解析畸形数字字符串(如"1,1.90.00")时,出现跨平台解析结果不一致的问题:

  • 标准Kotlin环境中,解析结果为11.90
  • Android Kotlin环境中,解析结果为1

该差异导致单元测试与仪器化测试结果不统一,且代码用于用户输入校验/修正场景,无法控制用户输入内容。

差异原因

标准JDK的NumberFormat实现与Android基于ICU的NumberFormat实现,对畸形输入的容错处理逻辑不同:

  • 标准JDK会尝试跳过无效分隔符,尽可能解析出合理数值
  • Android的ICU实现遇到第一个非法分隔符后就停止解析

解决方案:自定义统一解析逻辑

通过自定义字符串清理+解析逻辑,绕过系统NumberFormat的平台差异,确保跨平台解析结果一致。

实现代码

import java.text.DecimalFormatSymbols
import java.text.NumberFormat
import java.text.ParseException
import java.util.Locale

fun parseMalformedNumber(input: String, locale: Locale): Number? {
    val decimalSeparator = DecimalFormatSymbols.getInstance(locale).decimalSeparator
    val groupingSeparator = DecimalFormatSymbols.getInstance(locale).groupingSeparator

    // 移除所有千分位分组符(如美式Locale的逗号)
    var cleanedInput = input.replace(groupingSeparator.toString(), "")
    
    // 仅保留第一个小数点,后续的小数点全部移除
    val firstDecimalPos = cleanedInput.indexOf(decimalSeparator)
    if (firstDecimalPos != -1) {
        cleanedInput = buildString {
            append(cleanedInput.substring(0, firstDecimalPos + 1))
            append(cleanedInput.substring(firstDecimalPos + 1).replace(decimalSeparator.toString(), ""))
        }
    }
    
    // 清理所有非数字、非小数点的残留字符
    cleanedInput = cleanedInput.replace(Regex("[^\\d$decimalSeparator]"), "")

    return try {
        NumberFormat.getInstance(locale).parse(cleanedInput)
    } catch (e: ParseException) {
        null // 处理完全无法解析的无效输入
    }
}

使用示例

// 测试畸形输入"1,1.90.00"
val value = "1,1.90.00"
val parsed = parseMalformedNumber(value, Locale.US)
// 标准Kotlin与Android环境下,解析结果均为11.9000

逻辑说明

  1. 移除分组符:千分位分组符(如美式的逗号)仅用于格式化显示,不影响数值本身,直接移除
  2. 保留单个小数点:只保留第一个出现的小数点,后续的小数点视为无效输入移除
  3. 清理残留非法字符:确保最终输入仅包含数字和单个小数点
  4. 统一解析:使用系统NumberFormat处理清理后的合法字符串,保证跨平台结果一致

扩展调整

可根据实际业务需求调整清理规则:

  • 若允许负号,可在正则表达式中添加-,改为[^\\d$decimalSeparator-]
  • 若需要保留特定格式的输入,可调整分组符和小数点的处理逻辑

内容的提问来源于stack exchange,提问作者shilomig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 17:17:09