【发布时间】:2017-02-22 12:54:18
【问题描述】:
我正在开发一个必须索引某些句子的应用程序。目前使用 Java 和 PostgreSQL。句子可能使用多种语言,例如法语和西班牙语,使用重音符号和其他非 ASCII 符号。
对于每个单词,我想创建一个可索引的等价词,以便用户可以执行对重音不敏感的搜索(音译)。例如,当用户搜索“nacion”时,即使应用程序存储的原始单词是“Nación”,它也必须找到它。
对此最好的策略是什么?我不一定只限于 PostgreSQL,内部索引值也不需要与原始单词有任何相似之处。理想情况下,它应该是一个通用的解决方案,用于将任何 Unicode 字符串转换为不区分大小写和重音的 ASCII 字符串。
到目前为止,我正在使用如下所示的自定义函数,它只是在存储索引值之前将一些字母替换为 ASCII 等效项,并对查询字符串执行相同操作。
public String toIndexableASCII (String sStrIn) {
if (sStrIn==null) return null;
int iLen = sStrIn.length();
if (iLen==0) return sStrIn;
StringBuilder sStrBuff = new StringBuilder(iLen);
String sStr = sStrIn.toUpperCase();
for (int c=0; c<iLen; c++) {
switch (sStr.charAt(c)) {
case 'Á':
case 'À':
case 'Ä':
case 'Â':
case 'Å':
case 'Ã':
sStrBuff.append('A');
break;
case 'É':
case 'È':
case 'Ë':
case 'Ê':
sStrBuff.append('E');
break;
case 'Í':
case 'Ì':
case 'Ï':
case 'Î':
sStrBuff.append('I');
break;
case 'Ó':
case 'Ò':
case 'Ö':
case 'Ô':
case 'Ø':
sStrBuff.append('O');
break;
case 'Ú':
case 'Ù':
case 'Ü':
case 'Û':
sStrBuff.append('U');
break;
case 'Æ':
sStrBuff.append('E');
break;
case 'Ñ':
sStrBuff.append('N');
break;
case 'Ç':
sStrBuff.append('C');
break;
case 'ß':
sStrBuff.append('B');
break;
case (char)255:
sStrBuff.append('_');
break;
default:
sStrBuff.append(sStr.charAt(c));
}
}
return sStrBuff.toString();
}
【问题讨论】:
-
将字节解释为 ASCII 7 不会提供我想要实现的“信息丢失”。我希望“coraçón”与“coracon”相同,这样用户在搜索时是否输入重音并不重要。我不需要像谷歌这样的拼写或接近检查器“你的意思是......?”但我确实需要 "é" == "e"。
-
您询问的映射称为“音译”。
-
谢谢。我编辑了问题以添加音译,还帮助我谷歌了一些很好的匹配。
标签: indexing ascii non-ascii-characters transliteration