Dart中如何对不同编码的字符串进行相等性比较
Dart跨编码字符串相等性比较与编码转换方案
1. Dart默认编码说明
- Dart运行时的
String类型默认使用UTF-16编码存储,所有内置字符串操作(包括==相等性判断、下标取值、正则匹配等)均基于UTF-16码点执行。 - 主流Dart HTTP库(比如Dio、http)默认使用UTF-8编码解析服务端返回的字节流,若服务端返回内容的编码非UTF-8(如GBK、ISO-8859-1等),直接使用库转换好的String会出现码点解析错误,最终表现为肉眼可见字符一致、但
==比较失败、utf8.encode结果不同。
2. 跨编码字符串相等性比较方案
核心原则:保证两个对比的字符串是通过同一种编码规则解析得到的标准Dart String,再做相等性判断才会准确,具体可根据你的场景选择对应方案。
方案1:已知服务端编码,先转码再比较
优先推荐该方案,转码后得到的字符串可直接用于后续所有业务逻辑:
- 发送请求时配置HTTP参数,拿到服务端返回的原始字节流,不要使用框架自动转码完成的String结果。以Dio为例:
import 'package:dio/dio.dart'; import 'package:gbk_codec/gbk_codec.dart'; // 非UTF-8编码需引入对应编解码库 // 请求时设置响应类型为bytes Response<List<int>> resp = await Dio().get( '你的服务端接口地址', options: Options(responseType: ResponseType.bytes), ); // 用服务端实际使用的编码解码字节流为Dart String // 若服务端为UTF-8编码:String serverStr = utf8.decode(resp.data!); String serverStr = gbk.decode(resp.data!); // 直接用==和本地字符串比较即可 bool isEqual = serverStr == localStr;
方案2:未知服务端编码,直接对比编码后的字节数组
如果不需要使用服务端字符串的业务内容,仅需要判断相等性,可以直接将两个字符串统一转为同一种编码的字节数组,逐位对比即可:
import 'dart:convert'; bool checkStringEqual(String str1, String str2) { final bytes1 = utf8.encode(str1); final bytes2 = utf8.encode(str2); if (bytes1.length != bytes2.length) return false; for (int i = 0; i < bytes1.length; i++) { if (bytes1[i] != bytes2[i]) return false; } return true; }
注意事项
如果确认编码规则一致但仍然比较失败,可打印两个字符串的runes属性查看完整UTF-16码点序列,排查是否存在零宽空格、首尾空白符、特殊转义字符等不可见内容的差异。
内容的提问来源于stack exchange,提问作者SkR
相关产品推荐
相关产品推荐

