使用字符分隔符在 C++ 中解析字符串,但在每个解析的子字符串中保留可重复的字符作为分隔符(C++ STL)

Posted

技术标签:

【中文标题】使用字符分隔符在 C++ 中解析字符串,但在每个解析的子字符串中保留可重复的字符作为分隔符(C++ STL)【英文标题】:Parse a string in C++ using char delimiter but keep repeatable chars as delimiter inside each parsed substring (C++ STL) 【发布时间】:2020-02-11 15:28:03 【问题描述】:

如何解析这个字符串:

std::string input_str = "-10-20--300---400";

像这样进入向量:

std::vector<string> output =  "-10", "20", "-300", "--400" ;

仅使用 C++ STL?

【问题讨论】:

作为一个老 C 程序员,我会使用 C 标准库中的 strspnstrcspn 函数。但如果你不喜欢,那就手工完成...... @SergeBallesta 有趣。但是,如果我尝试使用 stringstream 和 getline 解决方案并删除向量中的所有空元素呢?如果向量中有空元素,我只需在下一个元素的开头添加分隔符字符串“-”?我想可以有更有效的解决方案...... @1201ProgramAlarm 您可以以这种讽刺的方式回答所有 SO 问题。顺便说一句,非信息性:) 我认为您需要一个更好的分隔符,从而使任务更接近琐碎。 只需将第一次出现的- 替换为空格即可。然后在调整后的字符串上使用stringstream 【参考方案1】:

这里的问题是您希望将(可能是多个)分隔符与其字符串一起保留。由于我懒得手动实现标准库中已经存在的内容,并且由于 C 标准库明确包含在 C++ 中,我将使用 strspnstrcspn 函数来分隔起点和终点子串并将它们复制到向量中。

可能的代码是:

#include <string>
#include <vector>
#include <cstring>

std::vector<std::string> parse(std::string input_str) 
    static const char delim[] = "-";
    std::vector<std::string> resul;

    const char *ix = input_str.c_str();
    const char *sentinel = ix + input_str.size();

    while (ix < sentinel) 
        const char *end = ix + strspn(ix, delim); // end of delim sequence
        if (end < sentinel)                      // stop at end of string!
            end = end + strcspn(end, delim);      // go to next sequence
        
        resul.insert(resul.end(), std::string(ix, end-ix));
        ix = end;
        if (ix < sentinel) ix += 1; // skip delimiter if not at end of string
    
    return resul;

它给出了预期的向量,并将字符串的复制和分配限制在最低限度。也许相当 C-ish 但应该是正确的 C++ 并且 Clang 不会引发任何警告......

【讨论】:

以上是关于使用字符分隔符在 C++ 中解析字符串,但在每个解析的子字符串中保留可重复的字符作为分隔符(C++ STL)的主要内容,如果未能解决你的问题,请参考以下文章

C++ 字符串解析器问题

C++ 中的日期/时间解析

如何拆分字符串但在java中保留分隔符? [复制]

华为OD机试 2023最新 字符串重新排列字符串重新排序(C++ 100%)

C++ 中的 Unicode 字符串处理

C++ 字符串解析(python 风格)