搜索 API:为什么 "Ondřej" 匹配 "ondrej"?我需要在浏览器中模仿

Search API: How come "Ondřej" matches "ondrej"? I need to mimic that in browser

更新:最后我使用 Java6 Normalizer 找出哪些字符是 a-zA-Z 的扩展。所以现在所有奇怪的字符都被翻译成这 50 个 ASCII 字母。 typing/autocompleting.

时没有明显减速

GAE Search API 使用什么算法处理字符串?

出于优化目的(在浏览器中),我需要模拟在 "needle" 字符串与索引匹配之前对其进行的任何处理。 基本上它意味着将 "weird" 字符翻译成它们的 "boring" (和小写)表示:

是否有一些标准化的(或至少 "well known")翻译 table 这样我就不会漏掉一些字符?

使用 unidecode python 库。

>>> import unidecode
>>> unidecode.unidecode(u'ř')
'r'
>>> unidecode.unidecode(u'ě,é,ë,Ě,É,Ë')
'e,e,e,E,E,E'
>>> unidecode.unidecode(u'ě,é,ë,Ě,É,Ë').lower()
'e,e,e,e,e,e'

最后,我硬编码了一个映射,其中键是 "plain" 字符,值包含连接所有键的 "weird" 版本的字符串。 (在 Java 中每个 "weird" 字符都知道它的 "plain" 对应物是什么。)

在Java中你可以这样翻译:

String dropAccents(String weirdCharacter) {
    return java.text.Normalizer.normalize(weirdCharacter, Normalizer.Form.NFD).replaceAll("\p{InCombiningDiacriticalMarks}+", "");
}

...您将其称为 65..91(大写)和 97..123(小写)字符

JavaScript/Java 初始化此类地图的代码大约有 50 行相当短的代码。

translationTable.put("A", "ÀÁÂÃÄÅĀĂĄǍǞǠǺȀȂȦḀẠẢẤẦẨẪẬẮẰẲẴẶÅ");
translationTable.put("B", "ḂḄḆ");
translationTable.put("C", "ÇĆĈĊČḈ");
translationTable.put("D", "ĎḊḌḎḐḒ");
translationTable.put("E", "ÈÉÊËĒĔĖĘĚȄȆȨḔḖḘḚḜẸẺẼẾỀỂỄỆ");
translationTable.put("F", "Ḟ");
translationTable.put("G", "ĜĞĠĢǦǴḠ");
translationTable.put("H", "ĤȞḢḤḦḨḪ");
translationTable.put("I", "ÌÍÎÏĨĪĬĮİǏȈȊḬḮỈỊ");
translationTable.put("J", "Ĵ");
translationTable.put("K", "ĶǨḰḲḴK");
translationTable.put("L", "ĹĻĽḶḸḺḼ");
translationTable.put("M", "ḾṀṂ");
translationTable.put("N", "ÑŃŅŇǸṄṆṈṊ");
translationTable.put("O", "ÒÓÔÕÖŌŎŐƠǑǪǬȌȎȪȬȮȰṌṎṐṒỌỎỐỒỔỖỘỚỜỞỠỢ");
translationTable.put("P", "ṔṖ");
translationTable.put("R", "ŔŖŘȐȒṘṚṜṞ");
translationTable.put("S", "ŚŜŞŠȘṠṢṤṦṨ");
translationTable.put("T", "ŢŤȚṪṬṮṰ");
translationTable.put("U", "ÙÚÛÜŨŪŬŮŰŲƯǓǕǗǙǛȔȖṲṴṶṸṺỤỦỨỪỬỮỰ");
translationTable.put("V", "ṼṾ");
translationTable.put("W", "ŴẀẂẄẆẈ");
translationTable.put("X", "ẊẌ");
translationTable.put("Y", "ÝŶŸȲẎỲỴỶỸ");
translationTable.put("Z", "ŹŻŽẐẒẔ");
translationTable.put("a", "àáâãäåāăąǎǟǡǻȁȃȧḁạảấầẩẫậắằẳẵặ");
translationTable.put("b", "ḃḅḇ");
translationTable.put("c", "çćĉċčḉ");
translationTable.put("d", "ďḋḍḏḑḓ");
translationTable.put("e", "èéêëēĕėęěȅȇȩḕḗḙḛḝẹẻẽếềểễệ");
translationTable.put("f", "ḟ");
translationTable.put("g", "ĝğġģǧǵḡ");
translationTable.put("h", "ĥȟḣḥḧḩḫẖ");
translationTable.put("i", "ìíîïĩīĭįǐȉȋḭḯỉị");
translationTable.put("j", "ĵǰ");
translationTable.put("k", "ķǩḱḳḵ");
translationTable.put("l", "ĺļľḷḹḻḽ");
translationTable.put("m", "ḿṁṃ");
translationTable.put("n", "ñńņňǹṅṇṉṋ");
translationTable.put("o", "òóôõöōŏőơǒǫǭȍȏȫȭȯȱṍṏṑṓọỏốồổỗộớờởỡợ");
translationTable.put("p", "ṕṗ");
translationTable.put("r", "ŕŗřȑȓṙṛṝṟ");
translationTable.put("s", "śŝşšșṡṣṥṧṩ");
translationTable.put("t", "ţťțṫṭṯṱẗ");
translationTable.put("u", "ùúûüũūŭůűųưǔǖǘǚǜȕȗṳṵṷṹṻụủứừửữự");
translationTable.put("v", "ṽṿ");
translationTable.put("w", "ŵẁẃẅẇẉẘ");
translationTable.put("x", "ẋẍ");
translationTable.put("y", "ýÿŷȳẏẙỳỵỷỹ");
translationTable.put("z", "źżžẑẓẕ");