如何在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
相关产品推荐
相关产品推荐

