Tho*_* S. 7 string case-insensitive rust
要比较两个Strings,忽略大小写,看起来我首先需要转换为字符串的小写版本:
let a_lower = a.to_lowercase();
let b_lower = b.to_lowercase();
a_lower.cmp(&b_lower)
Run Code Online (Sandbox Code Playgroud)
是否有一种方法可以比较字符串,忽略大小写,而不创建临时小写字符串,即迭代字符,执行小写转换并比较结果?
如果您仅使用 ASCII,则可以使用eq_ignore_ascii_case:
assert!("Ferris".eq_ignore_ascii_case("FERRIS"));
Run Code Online (Sandbox Code Playgroud)
没有内置方法,但假设您只关心 ASCII 输入,您可以编写一个方法来完全按照您所描述的方式执行操作。
use itertools::{EitherOrBoth::*, Itertools as _}; // 0.9.0
use std::cmp::Ordering;
fn cmp_ignore_case_ascii(a: &str, b: &str) -> Ordering {
a.bytes()
.zip_longest(b.bytes())
.map(|ab| match ab {
Left(_) => Ordering::Greater,
Right(_) => Ordering::Less,
Both(a, b) => a.to_ascii_lowercase().cmp(&b.to_ascii_lowercase()),
})
.find(|&ordering| ordering != Ordering::Equal)
.unwrap_or(Ordering::Equal)
}
Run Code Online (Sandbox Code Playgroud)
正如下面的一些评论所指出的,如果不对整个字符串进行操作,不区分大小写的比较对于 UTF-8 将无法正常工作,即使如此,某些大小写转换也有多种表示形式,这可能会产生意外的结果。
考虑到这些注意事项,与上面的 ASCII 版本相比,以下内容将适用于许多额外情况(例如,最重音的拉丁字符),并且可能会令人满意,具体取决于您的要求:
fn cmp_ignore_case_utf8(a: &str, b: &str) -> Ordering {
a.chars()
.flat_map(char::to_lowercase)
.zip_longest(b.chars().flat_map(char::to_lowercase))
.map(|ab| match ab {
Left(_) => Ordering::Greater,
Right(_) => Ordering::Less,
Both(a, b) => a.cmp(&b),
})
.find(|&ordering| ordering != Ordering::Equal)
.unwrap_or(Ordering::Equal)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4251 次 |
| 最近记录: |