aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Leitner-Ankerl <martin.ankerl@gmail.com>2022-05-02 21:44:09 +0200
committerMartin Leitner-Ankerl <martin.ankerl@gmail.com>2022-05-04 07:34:47 +0200
commitb7ab9db545492927b774912e53aeb834a590621f (patch)
tree94b912439bd1e205a15e1a39438ee8861e3e057d /src
parent12455acca2c3adf5c88ae9c1a02a7c192fe0f53b (diff)
downloadbitcoin-b7ab9db545492927b774912e53aeb834a590621f.tar.xz
Extend Split to work with multiple separators
Diffstat (limited to 'src')
-rw-r--r--src/test/util_tests.cpp13
-rw-r--r--src/util/spanparsing.h20
-rw-r--r--src/util/string.h6
3 files changed, 36 insertions, 3 deletions
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index b880a7a9fd..890b2f997e 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -2396,6 +2396,19 @@ BOOST_AUTO_TEST_CASE(test_SplitString)
BOOST_CHECK_EQUAL(result.size(), 1);
BOOST_CHECK_EQUAL(result[0], "AAA");
}
+
+ // multiple split characters
+ {
+ using V = std::vector<std::string>;
+ BOOST_TEST(SplitString("a,b.c:d;e", ",;") == V({"a", "b.c:d", "e"}));
+ BOOST_TEST(SplitString("a,b.c:d;e", ",;:.") == V({"a", "b", "c", "d", "e"}));
+ BOOST_TEST(SplitString("a,b.c:d;e", "") == V({"a,b.c:d;e"}));
+ BOOST_TEST(SplitString("aaa", "bcdefg") == V({"aaa"}));
+ BOOST_TEST(SplitString("x\0a,b"s, "\0"s) == V({"x", "a,b"}));
+ BOOST_TEST(SplitString("x\0a,b"s, '\0') == V({"x", "a,b"}));
+ BOOST_TEST(SplitString("x\0a,b"s, "\0,"s) == V({"x", "a", "b"}));
+ BOOST_TEST(SplitString("abcdefg", "bcd") == V({"a", "", "", "efg"}));
+ }
}
BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
diff --git a/src/util/spanparsing.h b/src/util/spanparsing.h
index ebec8714a7..51795271de 100644
--- a/src/util/spanparsing.h
+++ b/src/util/spanparsing.h
@@ -8,6 +8,7 @@
#include <span.h>
#include <string>
+#include <string_view>
#include <vector>
namespace spanparsing {
@@ -36,7 +37,7 @@ bool Func(const std::string& str, Span<const char>& sp);
*/
Span<const char> Expr(Span<const char>& sp);
-/** Split a string on every instance of sep, returning a vector.
+/** Split a string on any char found in separators, returning a vector.
*
* If sep does not occur in sp, a singleton with the entirety of sp is returned.
*
@@ -44,13 +45,13 @@ Span<const char> Expr(Span<const char>& sp);
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
*/
template <typename T = Span<const char>>
-std::vector<T> Split(const Span<const char>& sp, char sep)
+std::vector<T> Split(const Span<const char>& sp, std::string_view separators)
{
std::vector<T> ret;
auto it = sp.begin();
auto start = it;
while (it != sp.end()) {
- if (*it == sep) {
+ if (separators.find(*it) != std::string::npos) {
ret.emplace_back(start, it);
start = it + 1;
}
@@ -60,6 +61,19 @@ std::vector<T> Split(const Span<const char>& sp, char sep)
return ret;
}
+/** Split a string on every instance of sep, returning a vector.
+ *
+ * If sep does not occur in sp, a singleton with the entirety of sp is returned.
+ *
+ * Note that this function does not care about braces, so splitting
+ * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
+ */
+template <typename T = Span<const char>>
+std::vector<T> Split(const Span<const char>& sp, char sep)
+{
+ return Split<T>(sp, std::string_view{&sep, 1});
+}
+
} // namespace spanparsing
#endif // BITCOIN_UTIL_SPANPARSING_H
diff --git a/src/util/string.h b/src/util/string.h
index 36b9787db4..2e91347b27 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -14,6 +14,7 @@
#include <locale>
#include <sstream>
#include <string>
+#include <string_view>
#include <vector>
[[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep)
@@ -21,6 +22,11 @@
return spanparsing::Split<std::string>(str, sep);
}
+[[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, std::string_view separators)
+{
+ return spanparsing::Split<std::string>(str, separators);
+}
+
[[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v")
{
std::string::size_type front = str.find_first_not_of(pattern);