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 在 文本处理
96,205 每月下载量
在 6 个 crate 中使用 (4 直接)
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_uppercase 和 to_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
- 使用
yeslogic-ucd-generate
重新生成(参见文件头部)。 - 为每个表格添加
#[allow(dead_code)]
以防止警告。 - 删除映射到自身的条目。例如,在 Vim 中:
:g/(\(\d\+\)), &\[\1\])/d
。