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

如何在Jetpack Compose中用正则处理非英文数字输入并避免崩溃?

解决Jetpack Compose中数字输入含逗号导致崩溃的问题

核心问题分析

你的正则仅支持英文小数点(.),但部分用户因系统语言/输入法设置,会输入逗号(,)作为小数点分隔符,导致验证失效,后续数据转换时引发崩溃。以下是几种直接可行的解决方案:


方案1:输入层拦截并统一格式

在TextField的onValueChange中直接过滤非法字符,将逗号自动替换为点,从源头避免无效输入:

var inputValue by remember { mutableStateOf("") }

TextField(
    value = inputValue,
    onValueChange = { newValue ->
        // 替换逗号为点,仅保留数字和点,且限制最多一个小数点
        val filtered = newValue.replace(',', '.')
            .filter { it.isDigit() || it == '.' }
            .let { raw ->
                if (raw.count { it == '.' } > 1) {
                    raw.substringBeforeLast('.') + raw.last()
                } else raw
            }
        inputValue = filtered
    },
    label = { Text("请输入数字") }
)

方案2:修改正则兼容两种分隔符

如果需要允许用户输入逗号或点,可调整正则同时支持两种分隔符,确保验证覆盖所有合法输入:

val regex = remember {
    // 支持逗号/点作为小数点,禁止开头为0、重复分隔符、以分隔符结尾
    Regex("^(?!0)(?!.*([.,])\\1.*|([.,])$)\\d{0,10}([.,]\\d{0,2})?$")
}

验证后处理数据时,统一将逗号替换为点再转换:

if (regex.matches(inputValue)) {
    val standardValue = inputValue.replace(',', '.')
    val number = standardValue.toDoubleOrNull()
    // 后续业务逻辑
}

方案3:适配本地化输入(更友好)

利用Android的NumberFormat适配用户系统默认的小数点分隔符,让输入符合用户使用习惯:

val numberFormat = remember { 
    NumberFormat.getInstance(Locale.getDefault()) as DecimalFormat 
}
val decimalSeparator = numberFormat.decimalFormatSymbols.decimalSeparator

var inputValue by remember { mutableStateOf("") }

TextField(
    value = inputValue,
    onValueChange = { newValue ->
        // 仅允许数字和系统默认的小数点分隔符
        val allowedChars = setOf(decimalSeparator) + ('0'..'9').toSet()
        val filtered = newValue.filter { allowedChars.contains(it) }
        // 限制最多一个分隔符
        val finalValue = if (filtered.count { it == decimalSeparator } > 1) {
            filtered.substringBeforeLast(decimalSeparator) + filtered.last()
        } else filtered
        inputValue = finalValue
    },
    label = { Text("请输入数字") }
)

// 解析输入时用本地化格式
val parsedNumber = try {
    numberFormat.parse(inputValue)?.toDouble()
} catch (e: ParseException) {
    null
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:43:18