Last active
January 16, 2020 11:08
-
-
Save michaelbacci/a9f038e682b83b58017ffc40a5c0f235 to your computer and use it in GitHub Desktop.
Split string in a very smart way using C++11 variadic templace : split(" str1 ::str2;;3.14,,", " :,", str1_var, str2_var, int_val);
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Copyright Michael Bacci - 2017 | |
//Apache 2.0 license | |
/** | |
* Split string in a smart way using C++11 variadic template. | |
* You can copy/paste this code in your library just citing the source. | |
*/ | |
#include <iostream> | |
#include <string> | |
#include <sstream> | |
#include <vector> | |
#include <iterator> | |
#include <cassert> | |
template<typename T> | |
std::vector<T> | |
split(const T &str, const T &delimiters) { | |
std::vector<T> v; | |
typename T::size_type start, pos = 0; | |
auto emplace = [&] { if (pos != start) v.emplace_back(str, start, pos - start); }; | |
{ | |
start = 0; | |
while ((pos = str.find_first_of(delimiters, start)) != T::npos) { | |
emplace(); | |
start = pos + 1; | |
} | |
pos = str.length(); | |
} | |
emplace(); | |
return v; | |
} | |
std::vector<std::string> | |
split(const std::string &str, const std::string &delimiters) { | |
return split<std::string>(str, delimiters); | |
} | |
template<typename T, typename... TArgs> | |
std::vector<std::string> | |
split(const std::string &str, const std::string &delimiters, T &arg, TArgs &...Fargs) { | |
std::vector<std::string> v; | |
std::string sub_str; | |
typename std::string::size_type start, pos; | |
start = 0; | |
while ((pos = str.find_first_of(delimiters, start)) != std::string::npos && pos == start) | |
start = pos + 1; | |
auto assign_to_arg = [&] (const std::string::size_type pos){ | |
std::string sub(str, start, pos - start); | |
v.push_back(sub); | |
std::stringstream ss; | |
ss << sub; | |
ss >> arg; | |
}; | |
if (pos != std::string::npos) { | |
assign_to_arg(pos); | |
sub_str = std::string(str.begin() + pos, str.end()); | |
auto sub_v = split(sub_str, delimiters, Fargs...); | |
v.insert(v.end(), sub_v.begin(), sub_v.end()); | |
} else if (start < str.length()) { | |
assign_to_arg(str.length()); | |
} | |
return v; | |
} | |
int main() { | |
std::string str; | |
int range_min; | |
int range_max; | |
float value; | |
for (auto s : split(" :STRING :3 - 8 -:- 967.314 ", "- :", str, range_min, range_max, value)) | |
std::cout << s << ";"; | |
std::cout << std::endl << str << ";" << range_min << ";" << range_max << ";" << value << ";" << std::endl << std::endl; | |
std::string first; | |
int second; | |
for (auto s : split("::::A 16::3-7,8:", ",- :", first, second)) | |
std::cout << s << ";"; | |
std::cout << std::endl << first << ";" << second << ";" << std::endl; | |
assert(split("::::", ",- :", first, second).size() == 0); | |
assert(split(": :COOL1: :COOL2;;COOL3--", " ;,- :", first).size() == 3); | |
assert(first == "COOL1"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The output is: