用撇号突出显示搜索词 android
Highlight search word with apostrophe android
我在 android 应用程序中使用 FTS4 来实现 full-text 搜索。应用程序中的数据来自 API,带有变音符号和重音符号。我在数据库中创建了 2 列,一列存储原始数据,另一列存储没有变音符号或重音符号的数据(使用 Normalizer 剥离)。当我搜索没有变音符号或重音符号的单词时,搜索成功执行。当我想突出显示在文本中找到的搜索查询时,问题就出现了。
例如。这句话 I got from SO:
James 问:“这是 Renée 和 Noël 的曾祖父母 1970 年的s-ish 避暑别墅,不是吗?”没有得到回答,他摇了摇头——然后走开了。
如果我 运行 搜索 Renee,它会突出显示 Renée,但是当我执行对 Renees 的搜索时,它会成功找到包含单词 Renée's 的文本,但由于撇号,它不会突出显示它。
Search Term: Renee
Highlighted Output: Renée
Search Term: Renees
Highlighted Output: <whitespace>Renée’ <-- doesn't show the expected output
Expected Output: Renée’s
如果我使用 replaceAll
删除所有撇号以突出显示搜索的查询,它会显示突出显示的单词 Renée's,但只会像这样显示撇号 -> Renée' 甚至突出了单词前的空格。但是如果段落中有更多的撇号被删除,它会将突出显示的单词推回更多。
基本上我想在显示给用户的段落中显示 Renée's 并突出显示整个单词,即使用户搜索 Renees 也是如此。
这是我用来突出显示搜索文本的代码:
if (searchQuery != null){
String paragraph = data.getParagraph();
SpannableStringBuilder sb = new SpannableStringBuilder(paragraph);
String normalizedText = Normalizer.normalize(paragraph, Normalizer.Form.NFD).replaceAll("\p{InCombiningDiacriticalMarks}+", "").toLowerCase();
//String normalizedText = Normalizer.normalize(paragraph, Normalizer.Form.NFD).replaceAll("\p{InCombiningDiacriticalMarks}+", "").replaceAll("'", "").toLowerCase(); //remove all apostrophes -- this works but pushes back the highlighted text color because it doesn't count all stripped apostrophes in the original paragraph.
Pattern word = Pattern.compile(searchQuery, Pattern.CASE_INSENSITIVE);
Matcher match = word.matcher(normalizedText);
while (match.find()) {
BackgroundColorSpan fcs = new BackgroundColorSpan(Color.YELLOW);
sb.setSpan(fcs, match.start(), match.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
text.setText(sb);
}
如何突出显示带有撇号的搜索词?
您可以在 searchQuery
:
中的每个字符之间添加 ['’]?
模式(匹配可选的 '
或 ’
字符)
Pattern word = Pattern.compile(TextUtils.join("['’]?", searchQuery.split("")), Pattern.CASE_INSENSITIVE);
这样,您将确保搜索词组匹配,即使其中任何地方只有一个撇号。
看到一个regex demo。
我在 android 应用程序中使用 FTS4 来实现 full-text 搜索。应用程序中的数据来自 API,带有变音符号和重音符号。我在数据库中创建了 2 列,一列存储原始数据,另一列存储没有变音符号或重音符号的数据(使用 Normalizer 剥离)。当我搜索没有变音符号或重音符号的单词时,搜索成功执行。当我想突出显示在文本中找到的搜索查询时,问题就出现了。
例如。这句话 I got from SO:
James 问:“这是 Renée 和 Noël 的曾祖父母 1970 年的s-ish 避暑别墅,不是吗?”没有得到回答,他摇了摇头——然后走开了。
如果我 运行 搜索 Renee,它会突出显示 Renée,但是当我执行对 Renees 的搜索时,它会成功找到包含单词 Renée's 的文本,但由于撇号,它不会突出显示它。
Search Term: Renee
Highlighted Output: Renée
Search Term: Renees
Highlighted Output: <whitespace>Renée’ <-- doesn't show the expected output
Expected Output: Renée’s
如果我使用 replaceAll
删除所有撇号以突出显示搜索的查询,它会显示突出显示的单词 Renée's,但只会像这样显示撇号 -> Renée' 甚至突出了单词前的空格。但是如果段落中有更多的撇号被删除,它会将突出显示的单词推回更多。
基本上我想在显示给用户的段落中显示 Renée's 并突出显示整个单词,即使用户搜索 Renees 也是如此。
这是我用来突出显示搜索文本的代码:
if (searchQuery != null){
String paragraph = data.getParagraph();
SpannableStringBuilder sb = new SpannableStringBuilder(paragraph);
String normalizedText = Normalizer.normalize(paragraph, Normalizer.Form.NFD).replaceAll("\p{InCombiningDiacriticalMarks}+", "").toLowerCase();
//String normalizedText = Normalizer.normalize(paragraph, Normalizer.Form.NFD).replaceAll("\p{InCombiningDiacriticalMarks}+", "").replaceAll("'", "").toLowerCase(); //remove all apostrophes -- this works but pushes back the highlighted text color because it doesn't count all stripped apostrophes in the original paragraph.
Pattern word = Pattern.compile(searchQuery, Pattern.CASE_INSENSITIVE);
Matcher match = word.matcher(normalizedText);
while (match.find()) {
BackgroundColorSpan fcs = new BackgroundColorSpan(Color.YELLOW);
sb.setSpan(fcs, match.start(), match.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
text.setText(sb);
}
如何突出显示带有撇号的搜索词?
您可以在 searchQuery
:
['’]?
模式(匹配可选的 '
或 ’
字符)
Pattern word = Pattern.compile(TextUtils.join("['’]?", searchQuery.split("")), Pattern.CASE_INSENSITIVE);
这样,您将确保搜索词组匹配,即使其中任何地方只有一个撇号。
看到一个regex demo。