From 0bf413ab8e24fd0c19c14782278fc94aa2d0de18 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 30 Jun 2010 18:03:09 -0700 Subject: 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 --- src/pkg/bytes/bytes.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/pkg/bytes/bytes.go') 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] +} -- cgit v1.3