是否存在支持多语言数字的natsort变体?适配国际化街道索引排序
解决多语言数字的自然排序问题
好问题!默认的natsort确实只默认识别ASCII数字,对于波斯语这类非拉丁脚本的数字,会被当作普通字符处理,没法按数字值排序。不过咱们可以通过自定义转换逻辑来扩展它,实现任意语言数字的自然排序。
核心思路
先把字符串中的非ASCII数字转换成对应的ASCII数字,再用natsort进行自然排序。这样不管是波斯语、阿拉伯语还是其他语言的数字,都能统一按数字值参与排序。
方案1:针对特定语言(比如波斯语)的转换
如果只需要处理某一种语言的数字,可以直接创建数字映射表来替换:
#! /usr/bin/python3 import locale from natsort import natsort_keygen, ns # 波斯语数字到ASCII数字的映射 persian_digit_map = {'۰':'0', '۱':'1', '۲':'2', '۳':'3', '۴':'4', '۵':'5', '۶':'6', '۷':'7', '۸':'8', '۹':'9'} # 替换字符串中的波斯语数字 def convert_persian_digits(s): return ''.join(persian_digit_map.get(char, char) for char in s) locale.setlocale(locale.LC_ALL, 'fa_IR.UTF-8') streets = [ "2 street", "1 street", "12 street", "11 street", "۲ street", "۱ street", "۱۲ street", "۱۱ street" ] # 生成带转换逻辑的自然排序key custom_natsort_key = natsort_keygen(key=convert_persian_digits, alg=ns.LOCALE) sorted_streets = sorted(streets, key=custom_natsort_key) print(sorted_streets)
运行这段代码后,输出会按数字值自然排序:
['1 street', '۱ street', '2 street', '۲ street', '11 street', '۱۱ street', '12 street', '۱۲ street']
方案2:通用多语言数字转换
如果需要支持任意语言的数字(比如阿拉伯语、印地语等),可以利用unicodedata模块来识别Unicode数字字符,自动转换为ASCII数字:
#! /usr/bin/python3 import locale import unicodedata from natsort import natsort_keygen, ns # 通用数字转换:将任意Unicode数字转为ASCII数字 def convert_unicode_digits(s): result = [] for char in s: try: # 获取字符对应的数字值,转为ASCII字符串 digit_value = unicodedata.digit(char) result.append(str(digit_value)) except ValueError: # 非数字字符直接保留 result.append(char) return ''.join(result) locale.setlocale(locale.LC_ALL, 'fa_IR.UTF-8') streets = [ "2 street", "1 street", "12 street", "11 street", "۲ street", "۱ street", "۱۲ street", "۱۱ street" ] custom_natsort_key = natsort_keygen(key=convert_unicode_digits, alg=ns.LOCALE) sorted_streets = sorted(streets, key=custom_natsort_key) print(sorted_streets)
这个方案更灵活,只要是Unicode标准定义的数字字符,都能被正确转换和排序。
关于natsort变体
目前natsort本身没有内置的直接支持所有语言数字的变体,但通过natsort_keygen的key参数传入自定义转换函数,就能完美扩展这个功能,满足任意语言数字的自然排序需求。
内容的提问来源于stack exchange,提问作者Hartmut Holzgraefe
相关产品推荐
相关产品推荐

