Flutter本地JSON阿拉伯语搜索如何统一Alif变体字符实现匹配
问题核心原因
当前匹配失效有3个直接原因:
- 你将Alif变体字符(أ、إ、آ等)直接放在发音符号删除列表中,逻辑错误:这类字符属于字母变体,不是需要删除的发音符号,应该统一替换为基础字母ا(U+0627)
- 搜索逻辑仅对JSON中存储的字段值做了清洗,没有对用户输入的查询词做相同规则的归一化,两边文本规则不统一自然无法匹配
- 现有发音符号列表存在错误:编码124对应ASCII字符
|,根本不是阿拉伯语发音符号,会导致文本中正常的竖线被误删;同时缺少了阿拉伯语长音连接符(Tatweel,U+0640)的处理
修正方案
1. 定义正确的阿拉伯语处理规则
先修正原有常量的错误,单独定义Alif变体的替换映射:
// 正确的阿拉伯语发音符号列表,移除错误的124、Alif变体编码 const Iterable<int> arabicTashkelChar = [ 1617, // Shadda(叠音符) 1614, // Fatha(开口符) 1611, // Tanwin Fath(开口鼻音符) 1615, // Damma(合口符) 1612, // Tanwin Damm(合口鼻音符) 1616, // Kasra(齐齿符) 1613, // Tanwin Kasr(齐齿鼻音符) 1618, // Sukun(静符) 1600, // Tatweel(长音连接符) ]; // Alif变体映射表,所有变体统一替换为基础ا const Map<String, String> arabicAlifVariants = { 'أ': 'ا', // 带上方海姆宰的Alif 'إ': 'ا', // 带下方海姆宰的Alif 'آ': 'ا', // 带叠音标记的Alif 'ٱ': 'ا', // 连读Alif };
2. 封装通用阿拉伯语文本归一化函数
所有需要参与匹配的文本(存储值、用户输入)都要经过这个函数处理,保证规则统一:
/// 阿拉伯语文本归一化工具,用于搜索场景的模糊匹配 String normalizeArabic(String input) { if (input.trim().isEmpty) return ''; String result = input.trim(); // 先移除首尾无效空格,解决JSON里color字段末尾带空格的问题 // 第一步:统一替换所有Alif变体为基础字母 arabicAlifVariants.forEach((variant, standard) { result = result.replaceAll(variant, standard); }); // 第二步:移除所有发音符号 result = result.replaceAll( RegExp(String.fromCharCodes(arabicTashkelChar)), '' ); // 可选宽松匹配优化(按需开启) // result = result.replaceAll('ى', 'ي'); // 把词尾的ى统一替换为ي // result = result.replaceAll('ة', 'ه'); // 把词尾的ة统一替换为ه return result; }
3. 修改搜索逻辑
对存储字段值、用户查询词同时做归一化后再匹配:
Future<void> searchJson(query) async { final jsondata = await rootBundle.loadString('assets/json/product.json'); final list = await json.decode(jsondata) as List<dynamic>; // 先归一化用户输入的查询词 final normalizedQuery = normalizeArabic(query.toString()); List data = list .where((map) { // 归一化存储的颜色字段 final normalizedColor = normalizeArabic(map['color'].toString()); return normalizedColor.contains(normalizedQuery); }) .toList(); setState(() { items = data; }); }
匹配效果
处理后:
- 存储值
أحمر会被归一化为احمر - 用户输入
أحمر归一化结果为احمر,输入احمر归一化结果也为احمر,两种输入都能正常匹配到结果 - 原有发音符号移除功能不受影响,比如
اللغَةُ الْعَرَبِيَّة仍会被正确处理为اللغة العربية
内容的提问来源于stack exchange,提问作者Abdullah Bahattab
相关产品推荐
相关产品推荐

