AK: Add String::find_all() and String::count()

This commit is contained in:
Maciej Zygmanowski 2021-05-19 13:29:23 +02:00 committed by Linus Groh
parent e9898a6031
commit 80077cea86
3 changed files with 56 additions and 6 deletions

View file

@ -303,11 +303,8 @@ bool String::equals_ignoring_case(const StringView& other) const
return StringUtils::equals_ignoring_case(view(), other); return StringUtils::equals_ignoring_case(view(), other);
} }
int String::replace(const String& needle, const String& replacement, bool all_occurrences) Vector<size_t> String::find_all(const String& needle) const
{ {
if (is_empty())
return 0;
Vector<size_t> positions; Vector<size_t> positions;
size_t start = 0, pos; size_t start = 0, pos;
for (;;) { for (;;) {
@ -317,11 +314,26 @@ int String::replace(const String& needle, const String& replacement, bool all_oc
pos = ptr - characters(); pos = ptr - characters();
positions.append(pos); positions.append(pos);
if (!all_occurrences)
break;
start = pos + 1; start = pos + 1;
} }
return positions;
}
int String::replace(const String& needle, const String& replacement, bool all_occurrences)
{
if (is_empty())
return 0;
Vector<size_t> positions;
if (all_occurrences) {
positions = find_all(needle);
} else {
auto pos = find(needle);
if (!pos.has_value())
return 0;
positions.append(pos.value());
}
if (!positions.size()) if (!positions.size())
return 0; return 0;
@ -338,6 +350,22 @@ int String::replace(const String& needle, const String& replacement, bool all_oc
return positions.size(); return positions.size();
} }
size_t String::count(const String& needle) const
{
size_t count = 0;
size_t start = 0, pos;
for (;;) {
const char* ptr = strstr(characters() + start, needle.characters());
if (!ptr)
break;
pos = ptr - characters();
count++;
start = pos + 1;
}
return count;
}
String String::reverse() const String String::reverse() const
{ {
StringBuilder reversed_string; StringBuilder reversed_string;

View file

@ -262,6 +262,8 @@ public:
[[nodiscard]] StringView view() const; [[nodiscard]] StringView view() const;
int replace(const String& needle, const String& replacement, bool all_occurrences = false); int replace(const String& needle, const String& replacement, bool all_occurrences = false);
size_t count(const String& needle) const;
Vector<size_t> find_all(const String& needle) const;
[[nodiscard]] String reverse() const; [[nodiscard]] String reverse() const;
template<typename T, typename... Rest> template<typename T, typename... Rest>

View file

@ -168,6 +168,26 @@ TEST_CASE(replace)
EXPECT(test_string == "111._.|||._.|||"); EXPECT(test_string == "111._.|||._.|||");
} }
TEST_CASE(count)
{
String test_string = "Well, hello Friends!";
u32 count = test_string.count("Friends");
EXPECT(count == 1);
count = test_string.count("ell");
EXPECT(count == 2);
count = test_string.count("!");
EXPECT(count == 1);
test_string = String("111._.111._.111");
count = test_string.count("111");
EXPECT(count == 3);
count = test_string.count("._.");
EXPECT(count == 2);
}
TEST_CASE(substring) TEST_CASE(substring)
{ {
String test = "abcdef"; String test = "abcdef";