Skip to content

Commit b7ab9db

Browse files
committed
Extend Split to work with multiple separators
1 parent 12455ac commit b7ab9db

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

src/test/util_tests.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,6 +2396,19 @@ BOOST_AUTO_TEST_CASE(test_SplitString)
23962396
BOOST_CHECK_EQUAL(result.size(), 1);
23972397
BOOST_CHECK_EQUAL(result[0], "AAA");
23982398
}
2399+
2400+
// multiple split characters
2401+
{
2402+
using V = std::vector<std::string>;
2403+
BOOST_TEST(SplitString("a,b.c:d;e", ",;") == V({"a", "b.c:d", "e"}));
2404+
BOOST_TEST(SplitString("a,b.c:d;e", ",;:.") == V({"a", "b", "c", "d", "e"}));
2405+
BOOST_TEST(SplitString("a,b.c:d;e", "") == V({"a,b.c:d;e"}));
2406+
BOOST_TEST(SplitString("aaa", "bcdefg") == V({"aaa"}));
2407+
BOOST_TEST(SplitString("x\0a,b"s, "\0"s) == V({"x", "a,b"}));
2408+
BOOST_TEST(SplitString("x\0a,b"s, '\0') == V({"x", "a,b"}));
2409+
BOOST_TEST(SplitString("x\0a,b"s, "\0,"s) == V({"x", "a", "b"}));
2410+
BOOST_TEST(SplitString("abcdefg", "bcd") == V({"a", "", "", "efg"}));
2411+
}
23992412
}
24002413

24012414
BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)

src/util/spanparsing.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <span.h>
99

1010
#include <string>
11+
#include <string_view>
1112
#include <vector>
1213

1314
namespace spanparsing {
@@ -36,21 +37,21 @@ bool Func(const std::string& str, Span<const char>& sp);
3637
*/
3738
Span<const char> Expr(Span<const char>& sp);
3839

39-
/** Split a string on every instance of sep, returning a vector.
40+
/** Split a string on any char found in separators, returning a vector.
4041
*
4142
* If sep does not occur in sp, a singleton with the entirety of sp is returned.
4243
*
4344
* Note that this function does not care about braces, so splitting
4445
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
4546
*/
4647
template <typename T = Span<const char>>
47-
std::vector<T> Split(const Span<const char>& sp, char sep)
48+
std::vector<T> Split(const Span<const char>& sp, std::string_view separators)
4849
{
4950
std::vector<T> ret;
5051
auto it = sp.begin();
5152
auto start = it;
5253
while (it != sp.end()) {
53-
if (*it == sep) {
54+
if (separators.find(*it) != std::string::npos) {
5455
ret.emplace_back(start, it);
5556
start = it + 1;
5657
}
@@ -60,6 +61,19 @@ std::vector<T> Split(const Span<const char>& sp, char sep)
6061
return ret;
6162
}
6263

64+
/** Split a string on every instance of sep, returning a vector.
65+
*
66+
* If sep does not occur in sp, a singleton with the entirety of sp is returned.
67+
*
68+
* Note that this function does not care about braces, so splitting
69+
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
70+
*/
71+
template <typename T = Span<const char>>
72+
std::vector<T> Split(const Span<const char>& sp, char sep)
73+
{
74+
return Split<T>(sp, std::string_view{&sep, 1});
75+
}
76+
6377
} // namespace spanparsing
6478

6579
#endif // BITCOIN_UTIL_SPANPARSING_H

src/util/string.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@
1414
#include <locale>
1515
#include <sstream>
1616
#include <string>
17+
#include <string_view>
1718
#include <vector>
1819

1920
[[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep)
2021
{
2122
return spanparsing::Split<std::string>(str, sep);
2223
}
2324

25+
[[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, std::string_view separators)
26+
{
27+
return spanparsing::Split<std::string>(str, separators);
28+
}
29+
2430
[[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v")
2531
{
2632
std::string::size_type front = str.find_first_not_of(pattern);

0 commit comments

Comments
 (0)