给卡帕多奇亚手作店做库存表,我卡在土耳其语字符排序上
工作室给卡帕多奇亚一家手作皂店供货第三年,上个月他们老板突然说要按土耳其语字母顺序列产品,因为本地顾客习惯看「Ç」开头的皂排在前头。我原来用 Python 的 sorted() 按 Unicode 码点排,结果「Çamlıca」「Ceviz」「Çiçek」乱成一锅粥——Ç 的码点比 C 大,但土耳其语里 Ç 排在 C 后面、D 前面,c 和 ç 是两个不同的字母,ğ、ı、İ、ö、ş、ü 同理。
试了 locale.strxfrm(‘tr_TR.UTF-8’),本机没装这个 locale,直接报错。而且就算装了,服务器上也不一定齐。后来翻 Python 文档发现有人提过用 ICU,太重了。最后自己写了张映射表:把土耳其语 29 个字母按官方顺序映射到 a–z 区间,排序前先逐字符替换,排完再换回来。
TR_ORDER = "abcçdefgğhıijklmnoöprsştuüvyz"
TR_MAP = {ch: chr(ord('a') + i) for i, ch in enumerate(TR_ORDER)}
TR_MAP.update({ch.upper(): chr(ord('A') + i) for i, ch in enumerate(TR_ORDER)})
def tr_key(s):
return ''.join(TR_MAP.get(c, c) for c in s)
sorted(products, key=lambda p: tr_key(p['name']))
实测 1200 条 SKU,排出来顺序和店老板用 Excel 土耳其语排序的结果完全一致。代价是映射表只覆盖土耳其语字母,如果产品名里混了阿拉伯语或希腊语字符,会退化成码点排序,不过那部分本来也不该按土耳其语排。
坑在于:ı(无点 i)和 i 是两个字母,İ(有点大写 I)和 I 也是。我一开始图省事只处理了小写,结果「İstanbul」开头的皂排到了「Isparta」后面,被老板截图发过来问「你们是不是不喜欢伊斯坦布尔」。另外 Python 的 casefold() 对土耳其语 i 的处理和德语完全不同,千万别拿它做大小写归一。
现在这张表已经塞进工作室的库存脚本里,每次导 CSV 前跑一遍。你们在土耳其做本地化排序时,是硬编码字母表还是用 ICU?有没有遇到过 ı 和 i 混排的坑?
0
赞同度 100% · 0 条评论 · 2 阅读
0 条评论
还没有评论,写下第一条。