C ++:处理子字符串本身带有逗号的逗号分隔字符串的最简单方法? [关闭]

Posted

技术标签:

【中文标题】C ++:处理子字符串本身带有逗号的逗号分隔字符串的最简单方法? [关闭]【英文标题】:C++: the easiest way to handle comma-delimited strings whose substrings have commas themselves? [closed] 【发布时间】:2020-04-04 19:00:41 【问题描述】:

这是一个例子:

str1 = "a, b, \"c, d, e\", f"

如果我要解析这个字符串:

stringstream ss(str1);
while (getline(ss,str,','))
    cout << str << endl;

输出如下:

a
 b
 "c
 d
 e"
 f

我在哪里寻找

a
 b
 c, d, e
 f

【问题讨论】:

首先想到的是使用正则表达式来解析输入 en.cppreference.com/w/cpp/regex 这样您就可以定义什么是字符串。 the easiest way - 在 github 上找到一个库。使用那个库。 这是标准的 csv 格式,所以是的,使用标准的 CSV 库 【参考方案1】:

正如他们在评论中建议的那样,最简单的方法是使用解析器库。

C++ 中最好的解析器库之一是Boost.Spirit。

这是一个如何使用 Boost.Spirit 解析格式的工作示例:

#include <iostream>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_parse.hpp>

#include <boost/variant.hpp>
#include <boost/variant/get.hpp>

using Element = boost::variant<
    std::string,
    std::vector<std::string>
    >;

std::ostream& operator<<(std::ostream& s, Element const& e) 
    switch(e.which()) 
    case 0:
        return s << boost::get<std::string>(e);
    case 1:
        for(auto const& a : boost::get<std::vector<std::string>>(e))
            s << a << ' ';
        return s;
    
    throw;


std::vector<Element> parse(std::string const& input) 
    namespace qi = boost::spirit::qi;
    using namespace std;
    using I = decltype(input.begin());
    using S = qi::space_type;

    struct string2 : string 
        using string::string;
        string2(char c) : string(1, c)  // Need this extra constructor for +qi::alnum.
    ;

    // Grammar.
    qi::rule<I, S, string2>         element        = +qi::alnum;
    qi::rule<I, S>                  open           = qi::lit('"');
    qi::rule<I, S>                  close          = qi::lit('"');
    qi::rule<I, S, vector<string>>  nested_element = open >> (element % ',') >> close;
    qi::rule<I, S, Element>         element2       = element | nested_element;
    qi::rule<I, S, vector<Element>> parser         = element2 % ',';

    vector<Element> result;

    auto cur = input.begin();
    if(!phrase_parse(cur, input.end(), parser, qi::space, result) || cur != input.end())
        throw "Failed to parse.";

    return result;


int main() 
    auto elements = parse("a, b, \"c, d, e\", f");
    for(auto const& e : elements)
        std::cout << e << '\n';

输出:

a
b
c d e 
f

【讨论】:

@sehe 你知道如何避免必须指定qi::rule&lt;I, S, ...&gt;,使用auto 不起作用吗? 我认为Element = boost::variant&lt; 可能有点矫枉过正,我怀疑这是一个 csv,所以你不必解析包裹在 "" 中的元素。

以上是关于C ++:处理子字符串本身带有逗号的逗号分隔字符串的最简单方法? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在批处理文件中拆分以逗号分隔的字符串并在循环中调用 sqlplus 函数

用双引号将每个字符串括在逗号分隔的字符串中

oracle中PLSQL存储过程中如何使用逗号分隔的集合(逗号分隔字符串转换为一个集合)

使用逗号分隔符将单个 CSV 列批量转换为多个

如何在Objective C中为每3位数字添加逗号?

如何插入包含单引号的字符串