如何在Rust中将字符串折叠起来?

Lam*_*iry 5 unicode rust

我正在编写一个简单的全文本搜索库,并且需要折叠大小写以检查两个单词是否相等。对于此用例,现有的.to_lowercase().to_uppercase()方法还不够

从crates.io的快速搜索中,我可以找到用于规范化和分词的库,但不能区分大小写。regex-syntax确实具有大小写折叠代码,但是未在其API中公开。

如果没有现有的解决方案,那我可能不得不自己动手

luc*_*trv 5

截至今天(2023 年),无壳板条箱看起来无人维护,而ICU4X 项目似乎是可行的方法。要应用箱子折叠,请参阅icu_casemap箱子。要根据语言相关的约定比较字符串,请参阅icu_collatorcrate。有关如何在 Rust 中正确排序单词的详细介绍,请参阅此处

\n

有关 Unicode 理论和算法的文档,请参阅Unicode 标准。\n特别是:

\n\n

有关 ICU4X 项目的文档,请参阅此处

\n

要使用 ICU4X,您可以添加主 crateicuCargo.toml访问单个模块(例如icu::collatoricu::datetime等),或者仅添加您实际需要的单个 crate(例如icu_collatoricu_datetime等)。

\n

要检查两个单词是否相等(无论大小写),您可以对字符串应用完整大小写折叠,然后检查二进制相等。为此,您可能想要icu_casemap::CaseMapper::fold_string。ICU4X 的最新版本包括默认情况下直接编译到库中的必需 Unicode 数据,但还有其他可用选项

\n

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

\n
use icu_casemap::CaseMapper;\n\nlet cm = CaseMapper::new();\n\n// Check if two strings are equivalent case insensitively\nassert_eq!(cm.fold_string("hEllO WorLd"), cm.fold_string("HELLO worlD"));\n\nassert_eq!(cm.fold_string("hEllO WorLd"), "hello world");\nassert_eq!(cm.fold_string("\xce\x93\xce\xb5\xce\xb9\xce\xac \xcf\x83\xce\xbf\xcf\x85 \xce\x9a\xcf\x8c\xcf\x83\xce\xbc\xce\xb5"), "\xce\xb3\xce\xb5\xce\xb9\xce\xac \xcf\x83\xce\xbf\xcf\x85 \xce\xba\xcf\x8c\xcf\x83\xce\xbc\xce\xb5");\nassert_eq!(cm.fold_string("\xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x87 \xe0\xa4\xa6\xe0\xa5\x81\xe0\xa4\xa8\xe0\xa4\xbf\xe0\xa4\xaf\xe0\xa4\xbe"), "\xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x87 \xe0\xa4\xa6\xe0\xa5\x81\xe0\xa4\xa8\xe0\xa4\xbf\xe0\xa4\xaf\xe0\xa4\xbe");\nassert_eq!(cm.fold_string("\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82 \xd0\xbc\xd0\xb8\xd1\x80"), "\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82 \xd0\xbc\xd0\xb8\xd1\x80");\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,当前icu_casemap板条箱不包括标准化,将来可能会添加,请参阅此处的讨论。

\n

否则,要根据与语言相关的约定来比较字符串,您可以使用 crate icu_collator,它允许自定义多个选项,例如强度和区域设置。您可以在这里找到几个示例。

\n