diff options
author | A. Unique TensorFlower <gardener@tensorflow.org> | 2018-03-16 10:10:16 -0700 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2018-03-16 10:14:17 -0700 |
commit | 386ba370d41e8872a9db0d45239d7b00c14ef309 (patch) | |
tree | b7aa83e59e1345fcc1fbf6cb89db5601966c91b3 /tensorflow/core/lib | |
parent | a0bd058ad1406585634330772bfda76fd27d87d7 (diff) |
Added StrContains, StartsWith, and EndsWith functions to str_util.h.
Marked contains, starts_with, ends_with, and consume StringPiece methods as deprecated.
This will allow tensorflow::StringPiece to be more easily replaced with absl::string_view (once the deprecated methods are removed) as absl::string_view does not contain those methods.
PiperOrigin-RevId: 189355316
Diffstat (limited to 'tensorflow/core/lib')
-rw-r--r-- | tensorflow/core/lib/core/stringpiece.h | 4 | ||||
-rw-r--r-- | tensorflow/core/lib/strings/str_util.cc | 21 | ||||
-rw-r--r-- | tensorflow/core/lib/strings/str_util.h | 15 | ||||
-rw-r--r-- | tensorflow/core/lib/strings/str_util_test.cc | 52 |
4 files changed, 90 insertions, 2 deletions
diff --git a/tensorflow/core/lib/core/stringpiece.h b/tensorflow/core/lib/core/stringpiece.h index 910e4d9e2a..79409cce4b 100644 --- a/tensorflow/core/lib/core/stringpiece.h +++ b/tensorflow/core/lib/core/stringpiece.h @@ -88,11 +88,13 @@ class StringPiece { size_t find(char c, size_t pos = 0) const; size_t rfind(char c, size_t pos = npos) const; + // DEPRECATED: Use tensorflow::str_util::StrContains instead. bool contains(StringPiece s) const; // Checks whether StringPiece starts with x and if so advances the beginning // of it to past the match. It's basically a shortcut for starts_with // followed by remove_prefix. + // DEPRECATED: Use tensorflow::str_util::ConsumePrefix instead. bool Consume(StringPiece x) { if (starts_with(x)) { remove_prefix(x.size_); @@ -113,10 +115,12 @@ class StringPiece { int compare(StringPiece b) const; // Return true iff "x" is a prefix of "*this" + // DEPRECATED: Use tensorflow::str_util::StartsWith instead. bool starts_with(StringPiece x) const { return ((size_ >= x.size_) && (memcmp(data_, x.data_, x.size_) == 0)); } // Return true iff "x" is a suffix of "*this" + // DEPRECATED: Use tensorflow::str_util::EndsWith instead. bool ends_with(StringPiece x) const { return ((size_ >= x.size_) && (memcmp(data_ + (size_ - x.size_), x.data_, x.size_) == 0)); diff --git a/tensorflow/core/lib/strings/str_util.cc b/tensorflow/core/lib/strings/str_util.cc index d28857803d..9dbb74f6b8 100644 --- a/tensorflow/core/lib/strings/str_util.cc +++ b/tensorflow/core/lib/strings/str_util.cc @@ -373,7 +373,7 @@ size_t RemoveWhitespaceContext(StringPiece* text) { } bool ConsumePrefix(StringPiece* s, StringPiece expected) { - if (s->starts_with(expected)) { + if (StartsWith(*s, expected)) { s->remove_prefix(expected.size()); return true; } @@ -381,7 +381,7 @@ bool ConsumePrefix(StringPiece* s, StringPiece expected) { } bool ConsumeSuffix(StringPiece* s, StringPiece expected) { - if (s->ends_with(expected)) { + if (EndsWith(*s, expected)) { s->remove_suffix(expected.size()); return true; } @@ -452,5 +452,22 @@ bool SplitAndParseAsFloats(StringPiece text, char delim, result); } +bool StrContains(StringPiece haystack, StringPiece needle) { + return std::search(haystack.begin(), haystack.end(), needle.begin(), + needle.end()) != haystack.end(); +} + +bool StartsWith(StringPiece text, StringPiece prefix) { + return prefix.empty() || + (text.size() >= prefix.size() && + memcmp(text.data(), prefix.data(), prefix.size()) == 0); +} + +bool EndsWith(StringPiece text, StringPiece suffix) { + return suffix.empty() || (text.size() >= suffix.size() && + memcmp(text.data() + (text.size() - suffix.size()), + suffix.data(), suffix.size()) == 0); +} + } // namespace str_util } // namespace tensorflow diff --git a/tensorflow/core/lib/strings/str_util.h b/tensorflow/core/lib/strings/str_util.h index 44c52850fa..f062eddef8 100644 --- a/tensorflow/core/lib/strings/str_util.h +++ b/tensorflow/core/lib/strings/str_util.h @@ -141,6 +141,21 @@ bool SplitAndParseAsInts(StringPiece text, char delim, bool SplitAndParseAsFloats(StringPiece text, char delim, std::vector<float>* result); +// StartsWith() +// +// Returns whether a given string `text` begins with `prefix`. +bool StartsWith(StringPiece text, StringPiece prefix); + +// EndsWith() +// +// Returns whether a given string `text` ends with `suffix`. +bool EndsWith(StringPiece text, StringPiece suffix); + +// StrContains() +// +// Returns whether a given string `haystack` contains the substring `needle`. +bool StrContains(StringPiece haystack, StringPiece needle); + // ------------------------------------------------------------------ // Implementation details below template <typename T> diff --git a/tensorflow/core/lib/strings/str_util_test.cc b/tensorflow/core/lib/strings/str_util_test.cc index 6d461241f7..63643c3e8e 100644 --- a/tensorflow/core/lib/strings/str_util_test.cc +++ b/tensorflow/core/lib/strings/str_util_test.cc @@ -430,4 +430,56 @@ TEST(StringReplace, EmptyStringReplaceAll) { EXPECT_EQ("", str_util::StringReplace("", "a", "X", /*replace_all=*/true)); } +TEST(StartsWith, Basic) { + const string s1( + "123" + "\0" + "456", + 7); + const StringPiece a("foobar"); + const StringPiece b(s1); + const StringPiece e; + EXPECT_TRUE(str_util::StartsWith(a, a)); + EXPECT_TRUE(str_util::StartsWith(a, "foo")); + EXPECT_TRUE(str_util::StartsWith(a, e)); + EXPECT_TRUE(str_util::StartsWith(b, s1)); + EXPECT_TRUE(str_util::StartsWith(b, b)); + EXPECT_TRUE(str_util::StartsWith(b, e)); + EXPECT_TRUE(str_util::StartsWith(e, "")); + EXPECT_FALSE(str_util::StartsWith(a, b)); + EXPECT_FALSE(str_util::StartsWith(b, a)); + EXPECT_FALSE(str_util::StartsWith(e, a)); +} + +TEST(EndsWith, Basic) { + const string s1( + "123" + "\0" + "456", + 7); + const StringPiece a("foobar"); + const StringPiece b(s1); + const StringPiece e; + EXPECT_TRUE(str_util::EndsWith(a, a)); + EXPECT_TRUE(str_util::EndsWith(a, "bar")); + EXPECT_TRUE(str_util::EndsWith(a, e)); + EXPECT_TRUE(str_util::EndsWith(b, s1)); + EXPECT_TRUE(str_util::EndsWith(b, b)); + EXPECT_TRUE(str_util::EndsWith(b, e)); + EXPECT_TRUE(str_util::EndsWith(e, "")); + EXPECT_FALSE(str_util::EndsWith(a, b)); + EXPECT_FALSE(str_util::EndsWith(b, a)); + EXPECT_FALSE(str_util::EndsWith(e, a)); +} + +TEST(StrContains, Basic) { + StringPiece a("abcdefg"); + StringPiece b("abcd"); + StringPiece c("efg"); + StringPiece d("gh"); + EXPECT_TRUE(str_util::StrContains(a, b)); + EXPECT_TRUE(str_util::StrContains(a, c)); + EXPECT_TRUE(!str_util::StrContains(a, d)); +} + } // namespace tensorflow |