You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:55:20