如何实现Python下符合shift-trimmed规则的排序以通过测试?
复现AWS PostgreSQL的shift-trimmed + backwards accent排序规则(Python)
需要在Python中复现AWS PostgreSQL的排序行为,该排序需遵循shift-trimmed(移位修剪,忽略空格、标点等非核心字符的主权重)和backwards accent(kb-true/[backwards 2])(重音反向排序)规则。尝试使用ICU的und-u-ka-shifted-kb-true Locale创建Collator后未通过测试,以下是可行的调整方案:
测试用例
names = [ "cote", "coté", "côte", "côté", "ReasonE", "Reason1", "ReasonĔ", "Reason Super", "ReasonÅ", "ReasonA", "Reasona", "Reasone", "death", "deluge", "de luge", "disílva John", "diSilva John", "di Silva Fred", "diSilva Fred", "disílva Fred", "di Silva John", ] expected = [ "cote", "côte", "coté", "côté", "death", "deluge", "de luge", "di Silva Fred", "diSilva Fred", "disílva Fred", "di Silva John", "diSilva John", "disílva John", "Reason1", "Reasona", "ReasonA", "ReasonÅ", "Reasone", "ReasonE", "ReasonĔ", "Reason Super", ] assert sorted(names, key=some_sort_key) == expected
最初尝试的代码
import icu loc = icu.Locale("und-u-ka-shifted-kb-true") c = icu.Collator.createInstance(loc) assert sorted(names, key=c.getSortKey) == expected
调整后的可行方案
问题出在默认Collator的大小写排序规则和强度设置上,需补充以下配置:
import icu # 初始化包含shift-trimmed和backwards accent规则的Locale loc = icu.Locale("und-u-ka-shifted-kb-true") collator = icu.Collator.createInstance(loc) # 设置小写优先,匹配测试用例中小写字母在大写前的排序逻辑 collator.setCaseFirst(icu.Collator.CaseFirst.LOWER) # 显式设置排序强度为TERTIARY,确保区分大小写、重音等细节 collator.setStrength(icu.Collator.TERTIARY) # 执行排序并验证 sorted_result = sorted(names, key=collator.getSortKey) assert sorted_result == expected
关键调整说明
- 小写优先设置:测试用例中
Reasona排在ReasonA之前,需通过setCaseFirst(icu.Collator.CaseFirst.LOWER)覆盖ICU默认的大小写排序逻辑。 - 排序强度:TERTIARY强度会区分基础字符、大小写、重音等所有细节,完全匹配PostgreSQL在该规则下的排序精度。
- Locale参数验证:
und-u-ka-shifted对应shift-trimmed规则(忽略空格、标点的主权重),kb-true对应backwards accent规则(重音排序方向反转),需确保使用的ICU版本支持这些扩展参数(建议使用ICU 60+版本)。
内容的提问来源于stack exchange,提问作者Marcel Wilson
相关产品推荐
相关产品推荐

