1 回答

TA貢獻2019條經驗 獲得超9個贊
一般來說,我建議使用Collator強度設置為 的Collator.PRIMARY來比較包含重音符號和不同大小寫的字符串(例如,Nvsn和évs e)。不幸的是,Collator沒有contains()功能。
所以我們將自己制作。
private static boolean contains(String source, String target) {
if (target.length() > source.length()) {
return false;
}
Collator collator = Collator.getInstance();
collator.setStrength(Collator.PRIMARY);
int end = source.length() - target.length() + 1;
for (int i = 0; i < end; i++) {
String sourceSubstring = source.substring(i, i + target.length());
if (collator.compare(sourceSubstring, target) == 0) {
return true;
}
}
return false;
}
這會迭代源字符串,并檢查與搜索目標長度相同的每個子字符串是否等于搜索目標(就 Collator 而言)。
例如,假設我們的源字符串是,"This is a Tèst"并且我們正在搜索單詞"test"。此方法將迭代每個四個字母的子字符串:
This
his
is i
s is
is
is a
s a
a T
a Tè
Tès
Tèst
一旦找到匹配項就會返回 true。由于強度設置為Collator.PRIMARY,整理器認為"Tèst"和"test"相等,因此我們的方法返回true。
此方法很可能需要進行更多優化,但這應該是一個合理的起點。
編輯RuleBasedCollator:一種可能的優化是利用排序規則鍵以及and的已知實現細節RuleBasedCollationKey(假設您的項目中有 Google 的 Guava):
private static boolean containsBytes(String source, String target) {
Collator collator = Collator.getInstance();
collator.setStrength(Collator.PRIMARY);
byte[] sourceBytes = dropLastFour(collator.getCollationKey(source).toByteArray());
byte[] targetBytes = dropLastFour(collator.getCollationKey(target).toByteArray());
return Bytes.indexOf(sourceBytes, targetBytes) >= 0;
}
private static byte[] dropLastFour(byte[] in) {
return Arrays.copyOf(in, in.length - 4);
}
這是相當脆弱的(可能不適用于所有語言環境),但在我的測試中,它的速度快了 2 倍到 10 倍。
編輯:要支持突出顯示,您應該轉換contains()為indexOf(),然后使用該信息:
private static int indexOf(String source, String target) {
if (target.length() > source.length()) {
return -1;
}
Collator collator = Collator.getInstance();
collator.setStrength(Collator.PRIMARY);
int end = source.length() - target.length() + 1;
for (int i = 0; i < end; i++) {
String sourceSubstring = source.substring(i, i + target.length());
if (collator.compare(sourceSubstring, target) == 0) {
return i;
}
}
return -1;
}
然后你可以像這樣應用它:
String guestWholeName = guest.getGuestFirstName() + " " + guest.getGuestLastName();
int wholeNameIndex = indexOf(guestWholeName, searchText);
if (wholeNameIndex > -1) {
Timber.d("guest name first : guest.getGuestFirstName() %s", guest.getGuestFirstName());
Timber.d("guest name last : guest.getGuestLastName() %s", guest.getGuestLastName());
int endPos = wholeNameIndex + searchText.length();
Spannable spannable = new SpannableString(guestWholeName);
Typeface firstNameFont = Typeface.createFromAsset(context.getAssets(), "fonts/Graphik-Semibold.otf");
spannable.setSpan(new CustomTypefaceSpan("", firstNameFont), wholeNameIndex, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Objects.requireNonNull(guestName).setText(spannable);
} else {
Objects.requireNonNull(guestName).setText(guestWholeName);
}
添加回答
舉報