aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/bytes/bytes.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-06-30 18:03:09 -0700
committerRuss Cox <rsc@golang.org>2010-06-30 18:03:09 -0700
commit0bf413ab8e24fd0c19c14782278fc94aa2d0de18 (patch)
treed380d0f33dc266caf1a33dcd6492fad0bf957ca1 /src/pkg/bytes/bytes.go
parent269df5827010fa29822d0ed655e104b559f1e870 (diff)
downloadgo-0bf413ab8e24fd0c19c14782278fc94aa2d0de18.tar.xz
bytes, strings: add Replace
This is the Replace I suggested in the review of CL 1114041. It's true that we already have regexp.MustCompile(regexp.QuoteMeta(old)).ReplaceAll(s, new) but because this Replace is doing a simpler job it is simpler to call and inherently more efficient. I will add the bytes implementation and tests to the CL after the strings one has been reviewed. R=r, cw CC=golang-dev https://golang.org/cl/1731048
Diffstat (limited to 'src/pkg/bytes/bytes.go')
-rw-r--r--src/pkg/bytes/bytes.go33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/pkg/bytes/bytes.go b/src/pkg/bytes/bytes.go
index 852e0f8529..64292ef648 100644
--- a/src/pkg/bytes/bytes.go
+++ b/src/pkg/bytes/bytes.go
@@ -462,3 +462,36 @@ func Runes(s []byte) []int {
}
return t
}
+
+// Replace returns a copy of the slice s with the first n
+// non-overlapping instances of old replaced by new.
+// If n <= 0, there is no limit on the number of replacements.
+func Replace(s, old, new []byte, n int) []byte {
+ // Compute number of replacements.
+ if m := Count(s, old); m == 0 {
+ return s // avoid allocation
+ } else if n <= 0 || m < n {
+ n = m
+ }
+
+ // Apply replacements to buffer.
+ t := make([]byte, len(s)+n*(len(new)-len(old)))
+ w := 0
+ start := 0
+ for i := 0; i < n; i++ {
+ j := start
+ if len(old) == 0 {
+ if i > 0 {
+ _, wid := utf8.DecodeRune(s[start:])
+ j += wid
+ }
+ } else {
+ j += Index(s[start:], old)
+ }
+ w += copy(t[w:], s[start:j])
+ w += copy(t[w:], new)
+ start = j + len(old)
+ }
+ w += copy(t[w:], s[start:])
+ return t[0:w]
+}