diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 8016c2d8c5..f9038c4fc9 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1246,6 +1246,12 @@ BOOST_AUTO_TEST_CASE(test_script_parsing) BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two"); BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three"); + results = Split(input, '#', /*include_sep=*/true); + BOOST_CHECK_EQUAL(results.size(), 3U); + BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#"); + BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two#"); + BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three"); + input = "*foo*bar*"; results = Split(input, '*'); BOOST_CHECK_EQUAL(results.size(), 4U); @@ -1253,6 +1259,13 @@ BOOST_AUTO_TEST_CASE(test_script_parsing) BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo"); BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar"); BOOST_CHECK_EQUAL(SpanToStr(results[3]), ""); + + results = Split(input, '*', /*include_sep=*/true); + BOOST_CHECK_EQUAL(results.size(), 4U); + BOOST_CHECK_EQUAL(SpanToStr(results[0]), "*"); + BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo*"); + BOOST_CHECK_EQUAL(SpanToStr(results[2]), "bar*"); + BOOST_CHECK_EQUAL(SpanToStr(results[3]), ""); } BOOST_AUTO_TEST_CASE(test_SplitString) diff --git a/src/util/string.h b/src/util/string.h index 4b87525627..330c2a2a61 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -100,18 +100,30 @@ void ReplaceAll(std::string& in_out, const std::string& search, const std::strin * * If sep does not occur in sp, a singleton with the entirety of sp is returned. * + * @param[in] include_sep Whether to include the separator at the end of the left side of the splits. + * * Note that this function does not care about braces, so splitting * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. + * + * If include_sep == true, splitting "foo(bar(1),2),3) on ',' + * will return: + * - foo(bar(1), + * - 2), + * - 3) */ template > -std::vector Split(const std::span& sp, std::string_view separators) +std::vector Split(const std::span& sp, std::string_view separators, bool include_sep = false) { std::vector ret; auto it = sp.begin(); auto start = it; while (it != sp.end()) { if (separators.find(*it) != std::string::npos) { - ret.emplace_back(start, it); + if (include_sep) { + ret.emplace_back(start, it + 1); + } else { + ret.emplace_back(start, it); + } start = it + 1; } ++it; @@ -128,9 +140,9 @@ std::vector Split(const std::span& sp, std::string_view separator * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. */ template > -std::vector Split(const std::span& sp, char sep) +std::vector Split(const std::span& sp, char sep, bool include_sep = false) { - return Split(sp, std::string_view{&sep, 1}); + return Split(sp, std::string_view{&sep, 1}, include_sep); } [[nodiscard]] inline std::vector SplitString(std::string_view str, char sep)