I'm surprised there is no this question already despite how popular this task might be. Is it possible to do it without writing your own parser? Two or more whitespaces in a row must be skipped. Here's my solution if not
vector<string> split_with_backslash(const string &s)
{
vector<string> ret;
const char *ps = s.c_str();
while (*ps++) {
std::stringstream ss;
switch (*ps) {
default:
ss << *ps;
break;
case ' ': case '\t': case '\n':
ret.push_back(ss.str());
ss.str(string());
ss.clear();
break;
case '\\':
if (!(*++ps == ' ' || *ps == '\t' || *ps == '\n'))
--ps;
break;
}
}
return ret;
}
I'm bad with cpp iterators, so I've used c_str()
EDIT: Adding the wordexp example for @MarekR. It is relevant to the question, because wordexp nicely handles the quotation marks/backspaces, but not the special symbols below.
Here I'm preparing the pipeline for execution. This way I get rid of the '|' sign, which wordexp doesn't eat, but there's still <>& (I don't consider & for simplicity.
vector<string> subcommands;
boost::split(subcommands, cpp_buf, boost::is_any_of("|"));
wordexp_t res;
switch (wordexp(subcommands.back().c_str(), &res, 0)) {
case 0:
break;
case WRDE_NOSPACE:
wordfree(&res);
default:
exit(EXIT_FAILURE);
}