From 9cee0fb8d71be0f54730784ed75ea8c04cbe89cb Mon Sep 17 00:00:00 2001 From: Christian Blach Date: Mon, 25 Sep 2023 00:47:45 +0200 Subject: [PATCH] added strings.CutSpace and bytes.CutSpace --- src/bytes/bytes.go | 14 ++++++++++++++ src/bytes/bytes_test.go | 24 ++++++++++++++++++++++++ src/strings/strings.go | 12 ++++++++++++ src/strings/strings_test.go | 25 +++++++++++++++++++++++++ 4 files changed, 75 insertions(+) diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go index 9ee66cae4e..e718fe262b 100644 --- a/src/bytes/bytes.go +++ b/src/bytes/bytes.go @@ -1377,6 +1377,20 @@ func CutPrefix(s, prefix []byte) (after []byte, found bool) { return s[len(prefix):], true } +// CutSpace slices s around the each instance of one or more consecutive white space +// characters, as defined by unicode.IsSpace, returning the text before and after the +// white space characters. The found result reports white space characters appears in s. +// If no whitespace characters appear in s, CutSpace returns s, nil, false. +// +// CutSpace returns slices of the original slice s, not copies. +func CutSpace(s []byte) (before, after []byte, found bool) { + i := indexFunc(s, unicode.IsSpace, true) + if i == -1 { + return s, nil, false + } + return s[:i], TrimLeftFunc(s[i:], unicode.IsSpace), true +} + // CutSuffix returns s without the provided ending suffix byte slice // and reports whether it found the suffix. // If s doesn't end with suffix, CutSuffix returns s, false. diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go index f0733edd3f..75f11e9263 100644 --- a/src/bytes/bytes_test.go +++ b/src/bytes/bytes_test.go @@ -1758,6 +1758,30 @@ func TestCutPrefix(t *testing.T) { } } +var cutSpaceTests = []struct { + s string + before, after string + found bool +}{ + {"abc", "abc", "", false}, + {" abc", "", "abc", true}, + {"ab c", "ab", "c", true}, + {"abc ", "abc", "", true}, + {"abc ", "abc", "", true}, + {" abc ", "", "abc ", true}, + {"a\u0085bc", "a", "bc", true}, + {"a\t\n\v\f\r\u0085\u00A0bc", "a", "bc", true}, + {"", "", "", false}, +} + +func TestCutSpace(t *testing.T) { + for _, tt := range cutSpaceTests { + if before, after, found := CutSpace([]byte(tt.s)); string(before) != tt.before || string(after) != tt.after || found != tt.found { + t.Errorf("Cut(%q) = %q, %q, %v, want %q, %q, %v", tt.s, before, after, found, tt.before, tt.after, tt.found) + } + } +} + var cutSuffixTests = []struct { s, sep string before string diff --git a/src/strings/strings.go b/src/strings/strings.go index ece7237c44..df83a0ec7a 100644 --- a/src/strings/strings.go +++ b/src/strings/strings.go @@ -1288,6 +1288,18 @@ func CutPrefix(s, prefix string) (after string, found bool) { return s[len(prefix):], true } +// CutSpace slices s around the each instance of one or more consecutive white space +// characters, as defined by unicode.IsSpace, returning the text before and after the +// white space characters. The found result reports white space characters appears in s. +// If no whitespace characters appear in s, CutSpace returns s, "", false. +func CutSpace(s string) (before, after string, found bool) { + i := indexFunc(s, unicode.IsSpace, true) + if i == -1 { + return s, "", false + } + return s[:i], TrimLeftFunc(s[i:], unicode.IsSpace), true +} + // CutSuffix returns s without the provided ending suffix string // and reports whether it found the suffix. // If s doesn't end with suffix, CutSuffix returns s, false. diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go index f93cf6842f..98293284b4 100644 --- a/src/strings/strings_test.go +++ b/src/strings/strings_test.go @@ -1677,6 +1677,31 @@ func TestCutPrefix(t *testing.T) { } } +var cutSpaceTests = []struct { + s string + before, after string + found bool +}{ + {"abc", "abc", "", false}, + {" abc", "", "abc", true}, + {"ab c", "ab", "c", true}, + {"abc ", "abc", "", true}, + {"abc ", "abc", "", true}, + {" abc ", "", "abc ", true}, + {"a\u0085bc", "a", "bc", true}, + {"a\t\n\v\f\r\u0085\u00A0bc", "a", "bc", true}, + {"", "", "", false}, +} + +func TestCutSpace(t *testing.T) { + for _, tt := range cutSpaceTests { + if before, after, found := CutSpace(tt.s); before != tt.before || after != tt.after || found != tt.found { + t.Errorf("CutSpace(%q) = %q, %q, %v, want %q, %q, %v", tt.s, before, after, found, tt.before, tt.after, tt.found) + } + } +} + + var cutSuffixTests = []struct { s, sep string before string