如何在Rust中按大写字母拆分字符串并将匹配项作为子串开头?
在Rust中拆分字符串,将大写字母作为下一个子串的开头
问题背景
需要拆分String类型的字符串,要求保留每个大写字母开头的子串,且大写字母作为下一个子串的开头,而非上一个子串的结尾。当前使用split_inclusive的实现不符合预期:
当前代码:
let s = String::from("AaaBbCc"); for block in s.split_inclusive(|c: char| c.is_uppercase()) { println!("{block}") }
当前输出:
A aaB bC c
期望输出:
Aaa Bb Cc
解决方案
核心思路是先定位所有大写字母的起始索引,再根据这些索引对字符串进行切片,确保每个子串从大写字母开始,到下一个大写字母之前结束(最后一个子串到字符串末尾)。
实现代码
fn split_on_next_upper(s: &str) -> impl Iterator<Item = &str> { // 收集所有大写字母的起始索引 let mut caps_indices = s.char_indices() .filter(|(_, c)| c.is_uppercase()) .map(|(i, _)| i) .collect::<Vec<_>>(); // 添加字符串末尾的索引,处理最后一段子串 caps_indices.push(s.len()); // 遍历相邻索引对,生成对应的子串切片 caps_indices.windows(2) .map(move |window| &s[window[0]..window[1]]) } fn main() { let s = String::from("AaaBbCc"); for block in split_on_next_upper(&s) { println!("{block}"); } }
代码说明
- 收集大写字母索引:通过
char_indices遍历字符串,筛选出所有大写字母的起始位置并存入数组。 - 补充末尾索引:将字符串长度加入索引数组,确保最后一段子串能截取到字符串末尾。
- 生成子串:通过
windows(2)获取相邻的索引对,以此为起止位置切片字符串,得到符合要求的子串。
为什么split_inclusive不适用
split_inclusive的逻辑是将匹配的字符作为当前子串的结尾,因此每次遇到大写字母时,会将该字母留在当前子串的末尾,导致后续子串从大写字母之后的字符开始,无法满足需求。
内容的提问来源于stack exchange,提问作者Pioneer_11
相关产品推荐
相关产品推荐

