Dart中double.parse()抛出无效双精度异常的原因及解决方法
问题原因
double.parse 抛出异常触发崩溃,本质是传入的字符串经过逗号替换后,仍不符合Dart的double类型解析规则。爬取网页DOM拿到的价格文本普遍存在脏数据,仅替换逗号为小数点无法覆盖所有异常场景,常见触发场景包括:
- 文本夹带货币符号、促销标签:如
"€14,99"、"折扣价9,99",替换逗号后仍存在非数字类字符,直接解析报错 - 千分位格式冲突:如
"1,299.00"类带千分位逗号的价格,全量替换逗号为点会得到"1.299.00",出现多个小数点无法解析 - 特殊空白字符:网页常携带不换行空格
\xa0、零宽空格等特殊字符,普通trim()无法清除字符串中间夹杂的这类空白 - 多价格拼接:同一个价格节点可能同时包含原价、折扣价两段文本,如
"19,99 12,99",替换后为多段数字拼接格式,无法解析 - 非数字占位:缺货、免费赠送的商品价格位置可能是
"暂无库存"、"Free"这类纯文本,无有效数字
修复代码
不要直接使用double.parse处理外部爬取的不可靠数据,先做全量文本清洗,再用double.tryParse做容错,避免单条脏数据导致整个列表加载崩溃。
- 先实现通用价格清洗解析方法:
double? parseWebPrice(String rawText) { if (rawText.trim().isEmpty) return null; // 移除所有数字、逗号、小数点之外的字符(货币符号、文字、特殊空格全过滤) String cleaned = rawText.replaceAll(RegExp(r'[^0-9,.]'), ''); // 区分千分位逗号和小数位逗号 cleaned = cleaned.replaceAllMapped(RegExp(r',(\d{3})'), (match) { final remainStr = cleaned.substring(match.end); // 逗号后3位后没有其他数字分隔符,判定为千分位逗号,直接删除 if (!remainStr.contains(RegExp(r'[,.]'))) { return match.group(1)!; } // 否则为小数分隔符,替换为点 return '.${match.group(1)}'; }); // 处理多小数点异常,仅保留最后一个小数点作为小数分隔符 if (cleaned.split('.').length > 2) { final parts = cleaned.split('.'); cleaned = '${parts.sublist(0, parts.length - 1).join()}.${parts.last}'; } return double.tryParse(cleaned); }
- 替换原循环中的价格解析逻辑:
var content = parser.parse(doc); var allBooks = content.querySelectorAll("div.facet__products div.prd-main-wrapper"); var prices = allBooks .map((e) => e.getElementsByClassName("prd-price")[0].text.trim()) .toList(); for (int i = 0; i < allBooks.length; i++) { final price = parseWebPrice(prices[i]); // 解析失败时可根据业务需求给默认值,或打日志排查对应脏数据 if (price == null) { print('价格解析异常,原始文本:${prices[i]}'); continue; } var name = names[i].toString(); var author = authors[i].toString(); var img = imgs[i].toString(); BookModel model = BookModel(name, author, img, price, "D.R"); controller.books.add(model); print(allBooks); }
调试建议
- 定位具体异常值时,直接在解析前打印
prices[i]的原始内容,可快速确认是哪类脏数据触发的问题 - 如果你爬取的站点价格格式统一(比如仅用逗号做小数分隔符、无千分位规则),可以简化清洗逻辑,只保留过滤非数字字符的步骤即可
- 所有来自网页爬取、用户输入的不可靠数据,做类型转换时优先用
tryParse系列方法,不要直接用强转换方法,避免不必要的崩溃
内容的提问来源于stack exchange,提问作者flutter app
相关产品推荐
相关产品推荐

