diff --git a/include/string.hpp b/include/string.hpp index 65bac8ee..4d2342b6 100644 --- a/include/string.hpp +++ b/include/string.hpp @@ -68,6 +68,7 @@ std::string join(const TContainer& container, std::string seperator = "") { } /** Splits a string into a vector of tokens. +If `maxTokens > 0`, limits the number of tokens. Tokens do not include the separator string. Examples: split("a+b+c", "+") // {"a", "b", "c"} @@ -76,7 +77,7 @@ Examples: split("", "+") // {} split("abc", "") // throws rack::Exception */ -std::vector split(const std::string& s, const std::string& seperator); +std::vector split(const std::string& s, const std::string& seperator, size_t maxTokens = 0); #if defined ARCH_WIN diff --git a/src/string.cpp b/src/string.cpp index 3b9ab7f6..eaf371a5 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -205,22 +205,28 @@ bool CaseInsensitiveCompare::operator()(const std::string& a, const std::string& } -std::vector split(const std::string& s, const std::string& separator) { +std::vector split(const std::string& s, const std::string& separator, size_t maxTokens) { if (separator.empty()) throw Exception("split(): separator cannot be empty string"); // Special case of empty string if (s == "") return {}; + if (maxTokens == 1) + return {s}; std::vector v; size_t sepLen = separator.size(); size_t start = 0; size_t end; while ((end = s.find(separator, start)) != std::string::npos) { + // Add token to vector std::string token = s.substr(start, end - start); v.push_back(token); // Don't include delimiter start = end + sepLen; + // Stop searching for tokens if we're at the token limit + if (maxTokens == v.size() + 1) + break; } v.push_back(s.substr(start));