Commit ab0e3e8e by Greg Falcon Committed by Copybara-Service

Add StrContainsIgnoreCase() to strings/match.h; all the other case-sensitive…

Add StrContainsIgnoreCase() to strings/match.h; all the other case-sensitive methods in this file have corresponding case-insensitive ones.

PiperOrigin-RevId: 516933773
Change-Id: Iaec41afd923b10bc493ad864c0ecfe85a1fe2db8
parent a8f3b9d6
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "absl/strings/match.h" #include "absl/strings/match.h"
#include "absl/strings/ascii.h"
#include "absl/strings/internal/memutil.h" #include "absl/strings/internal/memutil.h"
...@@ -27,6 +28,27 @@ bool EqualsIgnoreCase(absl::string_view piece1, ...@@ -27,6 +28,27 @@ bool EqualsIgnoreCase(absl::string_view piece1,
// memcasecmp uses absl::ascii_tolower(). // memcasecmp uses absl::ascii_tolower().
} }
bool StrContainsIgnoreCase(absl::string_view haystack,
absl::string_view needle) noexcept {
while (haystack.size() >= needle.size()) {
if (StartsWithIgnoreCase(haystack, needle)) return true;
haystack.remove_prefix(1);
}
return false;
}
bool StrContainsIgnoreCase(absl::string_view haystack,
char needle) noexcept {
char upper_needle = absl::ascii_toupper(static_cast<unsigned char>(needle));
char lower_needle = absl::ascii_tolower(static_cast<unsigned char>(needle));
if (upper_needle == lower_needle) {
return StrContains(haystack, needle);
} else {
const char both_cstr[3] = {lower_needle, upper_needle, '\0'};
return haystack.find_first_of(both_cstr) != absl::string_view::npos;
}
}
bool StartsWithIgnoreCase(absl::string_view text, bool StartsWithIgnoreCase(absl::string_view text,
absl::string_view prefix) noexcept { absl::string_view prefix) noexcept {
return (text.size() >= prefix.size()) && return (text.size() >= prefix.size()) &&
......
...@@ -72,6 +72,15 @@ inline bool EndsWith(absl::string_view text, ...@@ -72,6 +72,15 @@ inline bool EndsWith(absl::string_view text,
memcmp(text.data() + (text.size() - suffix.size()), suffix.data(), memcmp(text.data() + (text.size() - suffix.size()), suffix.data(),
suffix.size()) == 0); suffix.size()) == 0);
} }
// StrContainsIgnoreCase()
//
// Returns whether a given ASCII string `haystack` contains the ASCII substring
// `needle`, ignoring case in the comparison.
bool StrContainsIgnoreCase(absl::string_view haystack,
absl::string_view needle) noexcept;
bool StrContainsIgnoreCase(absl::string_view haystack,
char needle) noexcept;
// EqualsIgnoreCase() // EqualsIgnoreCase()
// //
......
...@@ -124,4 +124,48 @@ TEST(MatchTest, EndsWithIgnoreCase) { ...@@ -124,4 +124,48 @@ TEST(MatchTest, EndsWithIgnoreCase) {
EXPECT_FALSE(absl::EndsWithIgnoreCase("", "fo")); EXPECT_FALSE(absl::EndsWithIgnoreCase("", "fo"));
} }
TEST(MatchTest, ContainsIgnoreCase) {
EXPECT_TRUE(absl::StrContainsIgnoreCase("foo", "foo"));
EXPECT_TRUE(absl::StrContainsIgnoreCase("FOO", "Foo"));
EXPECT_TRUE(absl::StrContainsIgnoreCase("--FOO", "Foo"));
EXPECT_TRUE(absl::StrContainsIgnoreCase("FOO--", "Foo"));
EXPECT_FALSE(absl::StrContainsIgnoreCase("BAR", "Foo"));
EXPECT_FALSE(absl::StrContainsIgnoreCase("BAR", "Foo"));
EXPECT_TRUE(absl::StrContainsIgnoreCase("123456", "123456"));
EXPECT_TRUE(absl::StrContainsIgnoreCase("123456", "234"));
EXPECT_TRUE(absl::StrContainsIgnoreCase("", ""));
EXPECT_TRUE(absl::StrContainsIgnoreCase("abc", ""));
EXPECT_FALSE(absl::StrContainsIgnoreCase("", "a"));
}
TEST(MatchTest, ContainsCharIgnoreCase) {
absl::string_view a("AaBCdefg!");
absl::string_view b("AaBCd!");
EXPECT_TRUE(absl::StrContainsIgnoreCase(a, 'a'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(a, 'A'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(a, 'b'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(a, 'B'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(a, 'e'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(a, 'E'));
EXPECT_FALSE(absl::StrContainsIgnoreCase(a, 'h'));
EXPECT_FALSE(absl::StrContainsIgnoreCase(a, 'H'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(a, '!'));
EXPECT_FALSE(absl::StrContainsIgnoreCase(a, '?'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(b, 'a'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(b, 'A'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(b, 'b'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(b, 'B'));
EXPECT_FALSE(absl::StrContainsIgnoreCase(b, 'e'));
EXPECT_FALSE(absl::StrContainsIgnoreCase(b, 'E'));
EXPECT_FALSE(absl::StrContainsIgnoreCase(b, 'h'));
EXPECT_FALSE(absl::StrContainsIgnoreCase(b, 'H'));
EXPECT_TRUE(absl::StrContainsIgnoreCase(b, '!'));
EXPECT_FALSE(absl::StrContainsIgnoreCase(b, '?'));
EXPECT_FALSE(absl::StrContainsIgnoreCase("", 'a'));
EXPECT_FALSE(absl::StrContainsIgnoreCase("", 'A'));
EXPECT_FALSE(absl::StrContainsIgnoreCase("", '0'));
}
} // namespace } // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment