diff options
| author | Russ Cox <rsc@golang.org> | 2010-06-30 18:03:09 -0700 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-06-30 18:03:09 -0700 |
| commit | 0bf413ab8e24fd0c19c14782278fc94aa2d0de18 (patch) | |
| tree | d380d0f33dc266caf1a33dcd6492fad0bf957ca1 /src/pkg/strings/strings.go | |
| parent | 269df5827010fa29822d0ed655e104b559f1e870 (diff) | |
| download | go-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/strings/strings.go')
| -rw-r--r-- | src/pkg/strings/strings.go | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/pkg/strings/strings.go b/src/pkg/strings/strings.go index c192b1826e..5de83250c1 100644 --- a/src/pkg/strings/strings.go +++ b/src/pkg/strings/strings.go @@ -459,3 +459,51 @@ func TrimRight(s string, cutset string) string { func TrimSpace(s string) string { return TrimFunc(s, unicode.IsSpace) } + +// Replace returns a copy of the string 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 string, n int) string { + if old == new { + return s // avoid allocation + } + + // 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.DecodeRuneInString(s[start:]) + j += wid + } + } else { + j += Index(s[start:], old) + } + w += copyString(t[w:], s[start:j]) + w += copyString(t[w:], new) + start = j + len(old) + } + w += copyString(t[w:], s[start:]) + return string(t[0:w]) +} + +func copyString(dst []byte, src string) int { + n := len(dst) + if n > len(src) { + n = len(src) + } + for i := 0; i < n; i++ { + dst[i] = src[i] + } + return n +} |
