1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
#pragma once
#include <string>
#include <iterator>
#include <vector>
namespace string
{
/**
* Splits the given string into pieces based on the given delimiters, storing
* the tokens at the end the given token container (which might be any container
* supporting insert iterators (std::vector, std::list, std::set, etc.)
*/
template <typename ContainerType>
inline void split(ContainerType& tokens, const std::string& subject, const std::string& delimiters,
bool trimEmpty = true)
{
std::string::size_type lastPos = 0;
std::string::size_type length = subject.length();
// Construct an output iterator which inserts elements at the end of the container
std::insert_iterator<ContainerType> output = std::inserter(tokens, tokens.end());
while (lastPos < length + 1)
{
// Find the next occurrence of any of the delimiters
std::string::size_type pos = subject.find_first_of(delimiters, lastPos);
// Nothing found, set the pos to trigger an exit
if (pos == std::string::npos)
{
pos = length;
}
// If the found position is different from the last occurrence, we have a non-empty token
// If the position is the same, this is an empty token, in which case we need to check the flag
if (pos != lastPos || !trimEmpty)
{
// Copy the range [lastPos..pos] from the subject and insert it into our token container
output = typename ContainerType::value_type(
subject.data() + lastPos,
static_cast<typename ContainerType::size_type>(pos - lastPos));
}
// Advance the cursor by one to skip the found delimiter
lastPos = pos + 1;
}
}
/**
* @brief Split the given string into parts, returning the result as a std::vector.
*
* Convenience wrapper for split() which does not require an existing container variable.
*/
inline std::vector<std::string> splitToVec(const std::string& subject,
const std::string& delimiters, bool trimEmpty = true)
{
std::vector<std::string> result;
split(result, subject, delimiters, trimEmpty);
return result;
}
}
|