Rust中如何分割字符串生成含带空格子串的向量?
如何在Rust中分割包含引号包裹内容的字符串?
直接用split(" ")会把引号内的空格也分割开,没法满足你的需求。这里提供几种实现思路,从手动实现到现成工具都有,适合不同场景:
1. 手动遍历字符串(适合理解原理)
自己处理字符遍历,跟踪是否处于引号内、是否有转义字符,以此决定是否分割:
fn split_with_quotes(s: &str) -> Vec<String> { let mut result = Vec::new(); let mut current = String::new(); let mut in_quote = false; let mut escaped = false; for c in s.chars() { match c { // 遇到未转义的反斜杠,标记为转义状态 '\\' if !escaped => escaped = true, // 遇到未转义的双引号,切换引号内状态 '"' if !escaped => in_quote = !in_quote, // 遇到空格且不在引号内、未转义,分割当前内容 ' ' if !in_quote && !escaped => { if !current.is_empty() { result.push(current); current = String::new(); } } // 其他字符,先处理转义再加入当前字符串 _ => { if escaped { current.push('\\'); escaped = false; } current.push(c); } } } // 加入最后一段内容 if !current.is_empty() { result.push(current); } result } fn main() { let hello = r##"#[0] !sell 0 100 ars \"belo lemon\" 1"##; let mut x = split_with_quotes(hello); // 去掉元素开头的!,匹配你的期望输出 x.iter_mut().for_each(|s| *s = s.trim_start_matches('!').to_string()); println!("{x:?}"); }
2. 使用正则表达式(灵活适配不同格式)
借助regex crate,用正则匹配引号包裹的内容或连续非空格字符:
首先在Cargo.toml添加依赖:
[dependencies] regex = "1.10"
然后实现代码:
use regex::Regex; fn main() { let hello = r##"#[0] !sell 0 100 ars \"belo lemon\" 1"##; // 正则匹配:要么是引号包裹的内容(支持转义),要么是非空格连续字符 let re = Regex::new(r#""(?:\\.|[^"])*"|\S+"#).unwrap(); let mut x: Vec<String> = re.find_iter(hello) .map(|m| m.as_str().to_string()) // 去掉引号并还原转义的引号 .map(|s| { if s.starts_with('"') && s.ends_with('"') { let inner = &s[1..s.len()-1]; inner.replace(r#"\"#, r#"""#) } else { s } }) // 去掉元素开头的! .map(|s| s.trim_start_matches('!').to_string()) .collect(); println!("{x:?}"); }
3. 使用现成工具库(最省心的方案)
如果你的场景类似命令行参数解析,直接用shellwords crate,它专门处理这种带引号的字符串分割:
在Cargo.toml添加依赖:
[dependencies] shellwords = "1.1"
代码实现非常简洁:
use shellwords::split; fn main() { let hello = r##"#[0] !sell 0 100 ars \"belo lemon\" 1"##; let mut x = split(hello).unwrap(); // 去掉元素开头的! x.iter_mut().for_each(|s| *s = s.trim_start_matches('!').to_string()); println!("{x:?}"); }
总结
- 手动实现适合学习字符串处理的底层逻辑,但要注意处理转义、引号嵌套等边界情况;
- 正则表达式灵活,能适配多种自定义格式,但需要熟悉正则语法;
- 现成库最省心,能覆盖大部分常见场景,推荐作为生产代码的首选。
内容的提问来源于stack exchange,提问作者Grunch
相关产品推荐
相关产品推荐

