如何在 Rust 中对字符串进行大小写折叠?

2024-01-03

我正在编写一个简单的全文搜索库,需要大小写折叠来检查两个单词是否相等。对于此用例,现有的.to_lowercase() https://doc.rust-lang.org/std/primitive.str.html#method.to_lowercase and .to_uppercase() https://doc.rust-lang.org/std/primitive.str.html#method.to_uppercase方法是不够 https://www.w3.org/International/wiki/Case_folding.

通过快速搜索 crates.io,我可以找到用于规范化和分词的库,但不能找到大小写折叠的库。regex-syntax确实有案例折叠代码 https://doc.rust-lang.org/regex/regex_syntax/struct.CharClass.html,但它没有在其 API 中公开。


截至今天(2023 年)caseless https://crates.io/crates/caseless板条箱看起来没有维护,而ICU4X项目 https://unicode-org.github.io/icu4x/docs/icu/似乎是要走的路。要应用大小写折叠,请参阅icu_casemap https://unicode-org.github.io/icu4x/docs/icu_casemap/箱。要根据语言相关约定比较字符串,请参阅icu_collator https://unicode-org.github.io/icu4x/docs/icu_collator/箱。有关如何在 Rust 中正确排序单词的详细介绍,请参阅here https://sts10.github.io/2023/01/29/sorting-words-alphabetically-rust.html.

有关 Unicode 理论和算法的文档,请参阅统一码标准 https://www.unicode.org/versions/Unicode15.0.0/。 尤其:

  • 大小写转换和大小写折叠:部分3.13 https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf#G33992 and 5.18 https://www.unicode.org/versions/Unicode15.0.0/ch05.pdf#G21180.
  • 校对算法 https://www.unicode.org/reports/tr10/

有关 ICU4X 项目的文档,请参阅here https://unicode-org.github.io/icu4x/docs/icu/.

要使用 ICU4X,您可以添加主包icu to Cargo.toml并访问单个模块(例如icu::collator, icu::datetime等),或者仅添加您实际需要的单个板条箱(例如icu_collator, icu_datetime, etc).

要检查两个单词是否相等(无论大小写),您可以对字符串应用完整大小写折叠,然后检查二进制相等。为此你可能想要icu_casemap::CaseMapper::fold_string。 ICU4X 的最新版本默认包含直接编译到库中的必要 Unicode 数据,但有其他可用选项 https://unicode-org.github.io/icu4x/docs/icu_provider/constructors/index.html.

这是一个简单的使用示例icu_casemap::CaseMapper:

use icu_casemap::CaseMapper;

let cm = CaseMapper::new();

// Check if two strings are equivalent case insensitively
assert_eq!(cm.fold_string("hEllO WorLd"), cm.fold_string("HELLO worlD"));

assert_eq!(cm.fold_string("hEllO WorLd"), "hello world");
assert_eq!(cm.fold_string("Γειά σου Κόσμε"), "γειά σου κόσμε");
assert_eq!(cm.fold_string("नमस्ते दुनिया"), "नमस्ते दुनिया");
assert_eq!(cm.fold_string("Привет мир"), "привет мир");

请注意,目前icu_casemapcrate 不包括标准化,将来可能会添加,请参阅讨论here https://github.com/unicode-org/icu4x/issues/3151#issuecomment-1457835904.

否则,要根据语言相关的约定比较字符串,您可以使用icu_collatorcrate,它允许自定义多个选项,例如强度和区域设置。你可以找到几个例子here https://unicode-org.github.io/icu4x/docs/icu_collator/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Rust 中对字符串进行大小写折叠? 的相关文章

随机推荐