Created
April 29, 2024 08:37
-
-
Save CaiJingLong/9cbd4a968512446400f4fb2a3e2ef999 to your computer and use it in GitHub Desktop.
拼音模糊匹配的方法,需要导入 pinyin 库 flutter pub add pinyin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:pinyin/pinyin.dart'; | |
class PinyinCompareResult { | |
final bool isMatch; | |
final String pinyin; | |
final Map<int, bool> matchIndex; | |
PinyinCompareResult({ | |
required this.isMatch, | |
required this.pinyin, | |
this.matchIndex = const {}, | |
}); | |
List<TextSpan> buildRich({ | |
Color matchColor = Colors.red, | |
Color normalColor = Colors.grey, | |
double fontSize = 13, | |
}) { | |
final normalStyle = TextStyle(color: normalColor, fontSize: fontSize); | |
final matchStyle = TextStyle(color: matchColor, fontSize: fontSize); | |
final List<TextSpan> textSpans = [ | |
TextSpan( | |
text: ' ', | |
style: normalStyle, | |
), | |
]; | |
var start = 0; | |
matchIndex.forEach((key, value) { | |
if (start < key) { | |
textSpans.add( | |
TextSpan( | |
text: pinyin.substring(start, key), | |
style: normalStyle, | |
), | |
); | |
} | |
textSpans.add( | |
TextSpan( | |
text: pinyin[key], | |
style: value ? matchStyle : normalStyle, | |
), | |
); | |
start = key + 1; | |
}); | |
if (start < pinyin.length) { | |
textSpans.add( | |
TextSpan( | |
text: pinyin.substring(start), | |
style: normalStyle, | |
), | |
); | |
} | |
return textSpans; | |
} | |
} | |
class PinyinUtils { | |
PinyinUtils._(); | |
/// 模糊匹配的方法 | |
static PinyinCompareResult checkPinyin({ | |
required String text, | |
required String inputPinyin, | |
}) { | |
if (text.trim().isEmpty) { | |
return PinyinCompareResult(isMatch: false, pinyin: ''); | |
} | |
final textPinyin = PinyinHelper.getPinyin(text, separator: ''); | |
if (inputPinyin.isEmpty) { | |
return PinyinCompareResult(isMatch: false, pinyin: textPinyin); | |
} | |
inputPinyin = inputPinyin.toLowerCase(); | |
final matchIndex = <int, bool>{}; | |
if (textPinyin.contains(inputPinyin)) { | |
final index = textPinyin.indexOf(inputPinyin); | |
for (var i = 0; i < inputPinyin.length; i++) { | |
matchIndex[index + i] = true; | |
} | |
return PinyinCompareResult( | |
isMatch: true, pinyin: textPinyin, matchIndex: matchIndex); | |
} | |
// 双指针查找法,查找是否包含输入的拼音 | |
// 比如 xiaomishouji 包含 xmsj、也包含 xmiouji ,只要顺序不错,即可匹配成功 | |
// 被查找的拼音指针 | |
var tPosition = 0; | |
// 输入的拼音指针 | |
var iPosition = 0; | |
for (; tPosition < textPinyin.length; tPosition++) { | |
if (textPinyin[tPosition] == inputPinyin[iPosition]) { | |
iPosition++; | |
matchIndex[tPosition] = true; | |
} | |
if (iPosition == inputPinyin.length) { | |
return PinyinCompareResult( | |
isMatch: true, | |
pinyin: textPinyin, | |
matchIndex: matchIndex, | |
); | |
} | |
} | |
return PinyinCompareResult(isMatch: false, pinyin: textPinyin); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment