diff options
| author | Russ Cox <rsc@golang.org> | 2011-09-26 18:32:51 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2011-09-26 18:32:51 -0400 |
| commit | a8a18f6566dd4af3335a587d10cec77f6c5a3e90 (patch) | |
| tree | 19e282d3578e0a57304a595801da4aeaefabb5cf /src/pkg/strings/strings.go | |
| parent | 1fa87ada553ec8b9d4e520fe715faa3f9d391a5c (diff) | |
| download | go-a8a18f6566dd4af3335a587d10cec77f6c5a3e90.tar.xz | |
strings: add EqualFold
Case-insensitive strcmp without using ToLower.
(Using ToLower is not always correct, and it allocates.)
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5143044
Diffstat (limited to 'src/pkg/strings/strings.go')
| -rw-r--r-- | src/pkg/strings/strings.go | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/pkg/strings/strings.go b/src/pkg/strings/strings.go index c547297e66..446fa3a0c8 100644 --- a/src/pkg/strings/strings.go +++ b/src/pkg/strings/strings.go @@ -583,3 +583,57 @@ func Replace(s, old, new string, n int) string { w += copy(t[w:], s[start:]) return string(t[0:w]) } + +// EqualFold returns true if s and t are equal under Unicode case-folding. +func EqualFold(s, t string) bool { + for s != "" && t != "" { + // Extract first rune from each string. + var sr, tr int + if s[0] < utf8.RuneSelf { + sr, s = int(s[0]), s[1:] + } else { + r, size := utf8.DecodeRuneInString(s) + sr, s = r, s[size:] + } + if t[0] < utf8.RuneSelf { + tr, t = int(t[0]), t[1:] + } else { + r, size := utf8.DecodeRuneInString(t) + tr, t = r, t[size:] + } + + // If they match, keep going; if not, return false. + + // Easy case. + if tr == sr { + continue + } + + // Make sr < tr to simplify what follows. + if tr < sr { + tr, sr = sr, tr + } + // Fast check for ASCII. + if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' { + // ASCII, and sr is upper case. tr must be lower case. + if tr == sr+'a'-'A' { + continue + } + return false + } + + // General case. SimpleFold(x) returns the next equivalent rune > x + // or wraps around to smaller values. + r := unicode.SimpleFold(sr) + for r != sr && r < tr { + r = unicode.SimpleFold(r) + } + if r == tr { + continue + } + return false + } + + // One string is empty. Are both? + return s == t +} |
