mirror of
https://github.com/golang/go
synced 2024-11-26 05:57:58 -07:00
strings, bytes: add CutPrefix and CutSuffix
Fixes #42537 Change-Id: Ie03c2614ffee30ebe707acad6b9f6c28fb134a45 Reviewed-on: https://go-review.googlesource.com/c/go/+/407176 Reviewed-by: Benny Siegert <bsiegert@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Changkun Ou <mail@changkun.de> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
0df7ad2e79
commit
68005592b3
4
api/next/42537.txt
Normal file
4
api/next/42537.txt
Normal file
@ -0,0 +1,4 @@
|
||||
pkg bytes, func CutPrefix([]uint8, []uint8) ([]uint8, bool) #42537
|
||||
pkg bytes, func CutSuffix([]uint8, []uint8) ([]uint8, bool) #42537
|
||||
pkg strings, func CutPrefix(string, string) (string, bool) #42537
|
||||
pkg strings, func CutSuffix(string, string) (string, bool) #42537
|
@ -1309,3 +1309,29 @@ func Clone(b []byte) []byte {
|
||||
}
|
||||
return append([]byte{}, b...)
|
||||
}
|
||||
|
||||
// CutPrefix returns s without the provided leading prefix byte slice
|
||||
// and reports whether it found the prefix.
|
||||
// If s doesn't start with prefix, CutPrefix returns s, false.
|
||||
// If prefix is the empty byte slice, CutPrefix returns s, true.
|
||||
//
|
||||
// CutPrefix returns slices of the original slice s, not copies.
|
||||
func CutPrefix(s, prefix []byte) (after []byte, found bool) {
|
||||
if !HasPrefix(s, prefix) {
|
||||
return s, false
|
||||
}
|
||||
return s[len(prefix):], 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.
|
||||
// If suffix is the empty byte slice, CutSuffix returns s, true.
|
||||
//
|
||||
// CutSuffix returns slices of the original slice s, not copies.
|
||||
func CutSuffix(s, suffix []byte) (after []byte, found bool) {
|
||||
if !HasSuffix(s, suffix) {
|
||||
return s, false
|
||||
}
|
||||
return s[:len(s)-len(suffix)], true
|
||||
}
|
||||
|
@ -1700,6 +1700,48 @@ func TestCut(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var cutPrefixTests = []struct {
|
||||
s, sep string
|
||||
after string
|
||||
found bool
|
||||
}{
|
||||
{"abc", "a", "bc", true},
|
||||
{"abc", "abc", "", true},
|
||||
{"abc", "", "abc", true},
|
||||
{"abc", "d", "abc", false},
|
||||
{"", "d", "", false},
|
||||
{"", "", "", true},
|
||||
}
|
||||
|
||||
func TestCutPrefix(t *testing.T) {
|
||||
for _, tt := range cutPrefixTests {
|
||||
if after, found := CutPrefix([]byte(tt.s), []byte(tt.sep)); string(after) != tt.after || found != tt.found {
|
||||
t.Errorf("CutPrefix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var cutSuffixTests = []struct {
|
||||
s, sep string
|
||||
after string
|
||||
found bool
|
||||
}{
|
||||
{"abc", "bc", "a", true},
|
||||
{"abc", "abc", "", true},
|
||||
{"abc", "", "abc", true},
|
||||
{"abc", "d", "abc", false},
|
||||
{"", "d", "", false},
|
||||
{"", "", "", true},
|
||||
}
|
||||
|
||||
func TestCutSuffix(t *testing.T) {
|
||||
for _, tt := range cutSuffixTests {
|
||||
if after, found := CutSuffix([]byte(tt.s), []byte(tt.sep)); string(after) != tt.after || found != tt.found {
|
||||
t.Errorf("CutSuffix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBufferGrowNegative(t *testing.T) {
|
||||
defer func() {
|
||||
if err := recover(); err == nil {
|
||||
|
@ -1187,3 +1187,25 @@ func Cut(s, sep string) (before, after string, found bool) {
|
||||
}
|
||||
return s, "", false
|
||||
}
|
||||
|
||||
// CutPrefix returns s without the provided leading prefix string
|
||||
// and reports whether it found the prefix.
|
||||
// If s doesn't start with prefix, CutPrefix returns s, false.
|
||||
// If prefix is the empty string, CutPrefix returns s, true.
|
||||
func CutPrefix(s, prefix string) (after string, found bool) {
|
||||
if !HasPrefix(s, prefix) {
|
||||
return s, false
|
||||
}
|
||||
return s[len(prefix):], 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.
|
||||
// If suffix is the empty string, CutSuffix returns s, true.
|
||||
func CutSuffix(s, suffix string) (after string, found bool) {
|
||||
if !HasSuffix(s, suffix) {
|
||||
return s, false
|
||||
}
|
||||
return s[:len(s)-len(suffix)], true
|
||||
}
|
||||
|
@ -1611,6 +1611,48 @@ func TestCut(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var cutPrefixTests = []struct {
|
||||
s, sep string
|
||||
after string
|
||||
found bool
|
||||
}{
|
||||
{"abc", "a", "bc", true},
|
||||
{"abc", "abc", "", true},
|
||||
{"abc", "", "abc", true},
|
||||
{"abc", "d", "abc", false},
|
||||
{"", "d", "", false},
|
||||
{"", "", "", true},
|
||||
}
|
||||
|
||||
func TestCutPrefix(t *testing.T) {
|
||||
for _, tt := range cutPrefixTests {
|
||||
if after, found := CutPrefix(tt.s, tt.sep); after != tt.after || found != tt.found {
|
||||
t.Errorf("CutPrefix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var cutSuffixTests = []struct {
|
||||
s, sep string
|
||||
after string
|
||||
found bool
|
||||
}{
|
||||
{"abc", "bc", "a", true},
|
||||
{"abc", "abc", "", true},
|
||||
{"abc", "", "abc", true},
|
||||
{"abc", "d", "abc", false},
|
||||
{"", "d", "", false},
|
||||
{"", "", "", true},
|
||||
}
|
||||
|
||||
func TestCutSuffix(t *testing.T) {
|
||||
for _, tt := range cutSuffixTests {
|
||||
if after, found := CutSuffix(tt.s, tt.sep); after != tt.after || found != tt.found {
|
||||
t.Errorf("CutSuffix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeBenchInputHard() string {
|
||||
tokens := [...]string{
|
||||
"<a>", "<p>", "<b>", "<strong>",
|
||||
|
Loading…
Reference in New Issue
Block a user