在我的Android应用程序的一部分中,你可以按名字搜索人。但我需要的是,即使名字或姓氏写错了(例如没有重音),结果也会显示出来:
示例:
数据库中:佩雷斯·胡安,库珀·谢尔顿,佩雷斯·禤浩焯
搜索:佩雷斯
节目:佩雷斯·胡安,佩雷斯·禤浩焯(来自数据库)
我使用LIKE执行查询,它覆盖了不敏感的大小写,但它不适用于重音,因为我必须写完全相同的字母(带或不带重音),以下是我的工作代码:
所以我得到了在搜索Person中使用的变量
String name = searchEditText.getText().toString();
if (!name.equals("")){
name = "%" + name + "%";
}
PersonDao
@Query("SELECT *, lastName || ' ' || name AS FullName\n" +
"FROM Person\n" +
"WHERE FullName LIKE :fn\n" +
"ORDER BY FullName")
LiveData<List<Person>> searchPerson(String fn);
StackOverflow找到可能的解决方案
为了解决我找到的this answer口音问题,我正在尝试实现该口音,但没有成功
所以我得到了在搜索Person中使用的变量
String name = searchEditText.getText().toString();
name = addTildeOptions(name);
addTildeOptions函数
private String addTildeOptions(String searchText) {
return searchText.toLowerCase()
.replaceAll("\\[aáàäâã]\\.*", "[aáàäâã]")
.replaceAll("\\[eéèëê]\\.*", "[eéèëê]")
.replaceAll("\\[iíìî]\\.*", "[iíìî]")
.replaceAll("\\[oóòöôõ]\\.*", "[oóòöôõ]")
.replaceAll("\\[uúùüû]\\.*", "[uúùüû]")
.replace("*", "[*]")
.replace("?", "[?]");
}
PersonDao
@Query("SELECT *, lastName || ' ' || name AS FullName\n" +
"FROM Person\n" +
"WHERE lower(FullName) GLOB :fn\n" +
"ORDER BY FullName")
LiveData<List<Person>> searchPerson(String fn);
但是,这不会返回任何结果,即使我输入一个字母,它也不会显示任何内容。
在获取EditText的文本时,我尝试在开始和结束处添加星号,尝试在PersonDao查询中输入addTildeOptions函数,如答案所示,但失败了,尝试了其他一些不相关的事情,但从未得到结果。
我的代码中有什么错误?
3条答案
按热度按时间vddsk6oq1#
较新的查询失败的原因是,您将一个大小写为
lower
的字符串传递给WHERE子句,而没有任何行与这些小写字符串匹配。例如,您的表包含“Pérez Juan”,而不是“Pérez Juan”addTildeOptions
函数是正确的,但您需要将其更改为替换所有普通元音和带有变音符号(波浪符号、重音符号、元音符号等)的元音。带一个‘?’字符,以便查询可以使用LIKE或GLOB查找行:然后只需删除
lower
调用并将GLOB保留在您的查询中:因此,搜索某个名称的所有变体将如下所示:
personDao.searchPerson(globPersonName(fn));
例如,
globPersonName("Perez Juan")
将返回P?r?z J??n
,您的查询应该找到“Pérez Juan”记录。pokxtpni2#
使用
GLOB
正是我所需要的。然而,我对其进行了一点修改,使其更加“细粒度”。例如,@zen_of_kermit的解决方案也会与“Poraz Jaen”匹配;但这不会:这样,每个元音都被其各自的正则表达式替换,因此它只匹配每个元音的已知变体。
cgyqldqp3#
对于那些在Kotlin工作的人:
并将SQL查询更改为: