#unicode-characters #unicode #lower-case #upper-case #case #title-case

unicode-case-mapping

字符的快速小写、大写和标题化映射

5 个版本 (破坏性)

0.5.0 2022年9月19日
0.4.0 2022年7月26日
0.3.0 2022年1月25日
0.2.0 2020年11月18日
0.1.0 2019年12月18日

#653文本处理

Download history 813/week @ 2024-03-14 1274/week @ 2024-03-21 847/week @ 2024-03-28 628/week @ 2024-04-04 846/week @ 2024-04-11 1064/week @ 2024-04-18 20620/week @ 2024-04-25 22642/week @ 2024-05-02 17467/week @ 2024-05-09 26445/week @ 2024-05-16 26199/week @ 2024-05-23 31158/week @ 2024-05-30 20475/week @ 2024-06-06 22693/week @ 2024-06-13 25618/week @ 2024-06-20 20129/week @ 2024-06-27

96,205 每月下载量
6 个 crate 中使用 (4 直接)

Apache-2.0

205KB
6.5K SLoC

unicode-case-mapping


使用 Unicode 15.0 数据在 Rust 中快速将字符映射为小写、大写、标题化或其简单的折叠

使用方法

fn main() {
    assert_eq!(unicode_case_mapping::to_lowercase('İ'), ['i' as u32, 0x0307]);
    assert_eq!(unicode_case_mapping::to_lowercase('ß'), ['ß' as u32, 0]);
    assert_eq!(unicode_case_mapping::to_uppercase('ß'), ['S' as u32, 'S' as u32, 0]);
    assert_eq!(unicode_case_mapping::to_titlecase('ß'), ['S' as u32, 's' as u32, 0]);
    assert_eq!(unicode_case_mapping::to_titlecase('-'), [0; 3]);
    assert_eq!(unicode_case_mapping::case_folded('I'), NonZeroU32::new('i' as u32));
    assert_eq!(unicode_case_mapping::case_folded('ß'), None);
    assert_eq!(unicode_case_mapping::case_folded(''), NonZeroU32::new('ß' as u32));
}

动机/何时使用

Rust 标准库为 char 提供了 to_uppercaseto_lowercase 方法,因此您可能想知道为什么创建了这个 crate 或者何时使用它。除非以下情况,否则您几乎肯定应该使用标准库:

  • 您需要支持标题化转换或根据 Unicode 字符数据库 (UCD) 进行折叠。
  • 您需要比标准库提供的迭代器接口更底层的访问映射表数据。
  • 您需要比标准库更快的性能。

创建此 crate 的另一个动机是能够独立于 Rust 版本版本化使用的 UCD 数据。这确保了我们所有的 Unicode 相关 crate 都使用相同的 UCD 版本。

性能 & 实现说明

ucd-generate 用于生成 tables.rs。构建脚本 (build.rs) 将其编译成一个三层查找表。查找时间恒定,因为它只是索引到数组中。

多级方法将代码点映射到块,然后映射到块中的位置,然后是该记录的索引,该记录描述如何将代码点映射到小写、大写和标题化。这允许数据去重,节省空间,同时提供快速查找。代码在块大小上参数化,块大小必须是 2 的幂。构建脚本中的值对于数据集是最佳的。

这种方法以牺牲一些空间为代价,以换取更快的查找速度。这些表格大约占用 101KiB 的空间。基准测试(使用 cargo bench 运行)显示,这种方法比 Rust 标准库中使用的二分查找方法快 ~5–10 倍。

可能还存在进一步的优化,可以消除第一级数组中的一些重复值的运行。

重新生成 tables.rs

  1. 使用 yeslogic-ucd-generate 重新生成(参见文件头部)。
  2. 为每个表格添加 #[allow(dead_code)] 以防止警告。
  3. 删除映射到自身的条目。例如,在 Vim 中::g/(\(\d\+\)), &\[\1\])/d

无运行时依赖