Mac文件路径对比时如何区分Unicode范式D中来自埃符号的字符
macOS路径Unicode字符串对比解决方案
核心对比逻辑
你之前的全量NFD规范化对比逻辑的问题在于,会将*Unicode规范化等价的单例字符(Singletones)*统一转换为组合字符序列,丢失原始编码差异。可使用分层对比逻辑解决:
- 先对来自变量的未规范化路径做定制化NFD处理:仅对非单例字符执行NFD规范化,所有单例字符保留原始编码不做转换
- 将处理后的路径直接与macOS系统返回的NFD范式路径做逐字节对比,即可同时满足组合字符匹配、单例字符区分的需求
规范化等价单例字符列表
Unicode标准中定义的规范化等价单例字符共26个,所有会触发你遇到的混淆问题的字符都属于这个集合,核心高频字符编码如下:
- U+00C5:带环大写拉丁字母A
- U+212B:埃符号
- U+03A9:希腊大写字母Omega
- U+2126:欧姆符号
- U+0192:带钩拉丁小写字母f
- U+2118:草体大写P
- U+2111:黑体大写I
- U+211C:黑体大写R
- U+2122:商标符号
- 其余字符均为组合变音符号类单例,在路径场景中出现概率极低,可通过Unicode字符数据库查询完整列表
参考实现(Python)
import unicodedata # 预定义所有规范化等价单例字符集合 NORM_SINGLETONS = { '\u00c5', '\u212b', '\u03a9', '\u2126', '\u0192', '\u2118', '\u2111', '\u211c', '\u2122', '\u212e', '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f' } def mac_path_compare(sys_nfd_path: str, input_path: str) -> bool: processed_input = [] for char in input_path: if char in NORM_SINGLETONS: processed_input.append(char) else: processed_input.append(unicodedata.normalize('NFD', char)) return ''.join(processed_input) == sys_nfd_path
注意事项
macOS的APFS、HFS+文件系统存储路径时,仅会对非单例的组合字符做NFD规范化,单例字符会保留用户写入时的原始编码,因此上述对比逻辑完全兼容系统原生路径存储规则。
内容的提问来源于stack exchange,提问作者Дмитрий Кузаков
相关产品推荐
相关产品推荐

