Skip to content

Instantly share code, notes, and snippets.

@CaiJingLong
Created April 29, 2024 08:37
Show Gist options
  • Save CaiJingLong/9cbd4a968512446400f4fb2a3e2ef999 to your computer and use it in GitHub Desktop.
Save CaiJingLong/9cbd4a968512446400f4fb2a3e2ef999 to your computer and use it in GitHub Desktop.
拼音模糊匹配的方法,需要导入 pinyin 库 flutter pub add pinyin
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