如何在C ++中使用类似shell的规则拆分字符串?

时间:2014-01-24 14:23:04

标签: c++ string shell parsing

我的字符串看起来像shell命令行:

string c = "/path/to/binary arg1 arg2 \"arg3 has multiple words\"";
string c2 = "/path/to/binary arg1 'arg2 could be single-quoted also';

我的目标很简单:我只想以类似于命令行shell的方式拆分字符串。我不是在寻找像通配符或环境变量扩展这样的奇特函数。我想将每个字符串拆分成各个部分:

vector<string> pieces = split_shell(c);
// pieces[0] == "/path/to/binary"
// pieces[1] == "arg1"
// pieces[2] == "arg2"
// pieces[3] == "arg3 has multiple words"

vector<string> pieces2 = split_shell(c2);
// pieces2[0] == "/path/to/binary"
// pieces2[1] == "arg1"
// pieces2[2] == "arg2 could be single-quoted also"

这显然不是很难通过沿着空格分割字符串然后迭代标记来合并那些被引号括起来的范围,但我不会重新发明轮子,除非我必须这样做。有没有一种干净的方法(在C ++ 03中)?我愿意使用Boost库;我怀疑使用Boost.Spirit可能会有一个简单的实现,但是我对它的熟悉程度还不够。

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

实际上,你可以通过正则表达式来实现,因为c ++ 03不支持正则表达式(c ++ 11),我们可以使用boost :: regex来完成这项工作。

#include <string>
#include <vector>
#include <iostream>

#include "boost/regex.hpp"

int main()
{
    //std::string str = "/path/to/binary arg1 arg2 \"arg3 has multiple words\"";
    std::string str = "/path/to/binary arg1 'arg2 could be single-quoted also'";

    //std::regex rx("([^(\"|')]\\S*|(\"|').+?(\"|'))\\s*");
    boost::regex rx("([^(\"|')]\\S*|(\"|').+?(\"|'))\\s*");
    boost::smatch res;
    while (boost::regex_search (str,res,rx))
    {
        std::cout <<res[0] << std::endl;
        str = res.suffix().str();
    }
    return 0;
}