在Rust中如何按单词迭代String类型?
在Rust中无需额外依赖实现按单词迭代
核心结论
Rust标准库没有专门的“按单词迭代”内置方法,但可以通过现有字符串方法组合或手动遍历的方式实现,完全不需要引入Regex这类额外依赖。
方法1:基于split和闭包的简单分割
适合将单词定义为“字母数字序列”的场景,把非字母数字字符作为分隔符:
fn main() { let s = "Hello, world! This is Rust 123."; let words: Vec<&str> = s .split(|c: char| !c.is_alphanumeric()) // 非字母数字字符作为分隔符 .filter(|segment| !segment.is_empty()) // 过滤连续分隔符产生的空字符串 .collect(); println!("{:?}", words); // 输出: ["Hello", "world", "This", "is", "Rust", "123"] }
方法2:自定义单词规则的分割
如果需要支持带特殊字符的单词(比如连字符组成的mother-in-law),可以调整分隔符的判断逻辑:
fn main() { let s = "Hello, world! Mother-in-law is coming -- let's go."; let words: Vec<&str> = s .split(|c: char| { // 仅将非字母数字、非连字符、非单引号的字符作为分隔符 !c.is_ascii_alphanumeric() && c != '-' && c != '\'' }) .filter(|segment| { // 过滤空字符串,同时确保片段包含有效单词字符 !segment.is_empty() && segment.chars().any(|c| c.is_ascii_alphanumeric()) }) .collect(); println!("{:?}", words); // 输出: ["Hello", "world", "Mother-in-law", "is", "coming", "let's", "go"] }
方法3:手动遍历字符索引(最灵活)
如果需要更复杂的单词规则(比如支持多语言字符、自定义分隔逻辑),可以通过char_indices手动遍历构建单词:
fn iter_words(s: &str) -> impl Iterator<Item = &str> { let mut start_idx = 0; let mut in_word = false; // 遍历每个字符的索引,截取单词片段 s.char_indices() .filter_map(move |(current_idx, c)| { // 自定义单词字符的判断逻辑,这里支持字母数字、连字符、单引号 let is_word_char = c.is_alphanumeric() || c == '-' || c == '\''; match (in_word, is_word_char) { // 从非单词字符进入单词字符,标记起始位置 (false, true) => { start_idx = current_idx; in_word = true; None } // 从单词字符进入非单词字符,截取当前单词 (true, false) => { in_word = false; Some(&s[start_idx..current_idx]) } // 其他情况(连续单词字符/连续非单词字符),不处理 _ => None, } }) // 处理字符串末尾的单词(如果最后一段是单词字符) .chain(if in_word { Some(&s[start_idx..]) } else { None }) } fn main() { let s = "Bonjour le monde! L'été est là -- c'est génial."; let words: Vec<_> = iter_words(s).collect(); println!("{:?}", words); // 输出: ["Bonjour", "le", "monde", "L'été", "est", "là", "c'est", "génial"] }
总结
- 简单场景用
split+闭包+过滤即可快速实现; - 复杂规则推荐手动遍历字符索引,完全自定义单词判断逻辑;
- 以上所有方式均无需引入额外依赖,仅使用Rust标准库即可完成。
内容的提问来源于stack exchange,提问作者Douglas Richard Landa
相关产品推荐
相关产品推荐

