...
Run Format

Source file src/strings/strings.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package strings implements simple functions to manipulate UTF-8 encoded strings.
     6	//
     7	// For information about UTF-8 strings in Go, see https://blog.golang.org/strings.
     8	package strings
     9	
    10	import (
    11		"unicode"
    12		"unicode/utf8"
    13	)
    14	
    15	// explode splits s into a slice of UTF-8 strings,
    16	// one string per Unicode character up to a maximum of n (n < 0 means no limit).
    17	// Invalid UTF-8 sequences become correct encodings of U+FFFD.
    18	func explode(s string, n int) []string {
    19		l := utf8.RuneCountInString(s)
    20		if n < 0 || n > l {
    21			n = l
    22		}
    23		a := make([]string, n)
    24		for i := 0; i < n-1; i++ {
    25			ch, size := utf8.DecodeRuneInString(s)
    26			a[i] = s[:size]
    27			s = s[size:]
    28			if ch == utf8.RuneError {
    29				a[i] = string(utf8.RuneError)
    30			}
    31		}
    32		if n > 0 {
    33			a[n-1] = s
    34		}
    35		return a
    36	}
    37	
    38	// primeRK is the prime base used in Rabin-Karp algorithm.
    39	const primeRK = 16777619
    40	
    41	// hashStr returns the hash and the appropriate multiplicative
    42	// factor for use in Rabin-Karp algorithm.
    43	func hashStr(sep string) (uint32, uint32) {
    44		hash := uint32(0)
    45		for i := 0; i < len(sep); i++ {
    46			hash = hash*primeRK + uint32(sep[i])
    47		}
    48		var pow, sq uint32 = 1, primeRK
    49		for i := len(sep); i > 0; i >>= 1 {
    50			if i&1 != 0 {
    51				pow *= sq
    52			}
    53			sq *= sq
    54		}
    55		return hash, pow
    56	}
    57	
    58	// hashStrRev returns the hash of the reverse of sep and the
    59	// appropriate multiplicative factor for use in Rabin-Karp algorithm.
    60	func hashStrRev(sep string) (uint32, uint32) {
    61		hash := uint32(0)
    62		for i := len(sep) - 1; i >= 0; i-- {
    63			hash = hash*primeRK + uint32(sep[i])
    64		}
    65		var pow, sq uint32 = 1, primeRK
    66		for i := len(sep); i > 0; i >>= 1 {
    67			if i&1 != 0 {
    68				pow *= sq
    69			}
    70			sq *= sq
    71		}
    72		return hash, pow
    73	}
    74	
    75	// Count counts the number of non-overlapping instances of sep in s.
    76	// If sep is an empty string, Count returns 1 + the number of Unicode code points in s.
    77	func Count(s, sep string) int {
    78		n := 0
    79		// special cases
    80		if len(sep) == 0 {
    81			return utf8.RuneCountInString(s) + 1
    82		}
    83		offset := 0
    84		for {
    85			i := Index(s[offset:], sep)
    86			if i == -1 {
    87				return n
    88			}
    89			n++
    90			offset += i + len(sep)
    91		}
    92	}
    93	
    94	// Contains reports whether substr is within s.
    95	func Contains(s, substr string) bool {
    96		return Index(s, substr) >= 0
    97	}
    98	
    99	// ContainsAny reports whether any Unicode code points in chars are within s.
   100	func ContainsAny(s, chars string) bool {
   101		return IndexAny(s, chars) >= 0
   102	}
   103	
   104	// ContainsRune reports whether the Unicode code point r is within s.
   105	func ContainsRune(s string, r rune) bool {
   106		return IndexRune(s, r) >= 0
   107	}
   108	
   109	// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
   110	func LastIndex(s, sep string) int {
   111		n := len(sep)
   112		switch {
   113		case n == 0:
   114			return len(s)
   115		case n == 1:
   116			return LastIndexByte(s, sep[0])
   117		case n == len(s):
   118			if sep == s {
   119				return 0
   120			}
   121			return -1
   122		case n > len(s):
   123			return -1
   124		}
   125		// Rabin-Karp search from the end of the string
   126		hashsep, pow := hashStrRev(sep)
   127		last := len(s) - n
   128		var h uint32
   129		for i := len(s) - 1; i >= last; i-- {
   130			h = h*primeRK + uint32(s[i])
   131		}
   132		if h == hashsep && s[last:] == sep {
   133			return last
   134		}
   135		for i := last - 1; i >= 0; i-- {
   136			h *= primeRK
   137			h += uint32(s[i])
   138			h -= pow * uint32(s[i+n])
   139			if h == hashsep && s[i:i+n] == sep {
   140				return i
   141			}
   142		}
   143		return -1
   144	}
   145	
   146	// IndexRune returns the index of the first instance of the Unicode code point
   147	// r, or -1 if rune is not present in s.
   148	// If r is utf8.RuneError, it returns the first instance of any
   149	// invalid UTF-8 byte sequence.
   150	func IndexRune(s string, r rune) int {
   151		switch {
   152		case 0 <= r && r < utf8.RuneSelf:
   153			return IndexByte(s, byte(r))
   154		case r == utf8.RuneError:
   155			for i, r := range s {
   156				if r == utf8.RuneError {
   157					return i
   158				}
   159			}
   160			return -1
   161		case !utf8.ValidRune(r):
   162			return -1
   163		default:
   164			return Index(s, string(r))
   165		}
   166	}
   167	
   168	// IndexAny returns the index of the first instance of any Unicode code point
   169	// from chars in s, or -1 if no Unicode code point from chars is present in s.
   170	func IndexAny(s, chars string) int {
   171		if len(chars) > 0 {
   172			if len(s) > 8 {
   173				if as, isASCII := makeASCIISet(chars); isASCII {
   174					for i := 0; i < len(s); i++ {
   175						if as.contains(s[i]) {
   176							return i
   177						}
   178					}
   179					return -1
   180				}
   181			}
   182			for i, c := range s {
   183				for _, m := range chars {
   184					if c == m {
   185						return i
   186					}
   187				}
   188			}
   189		}
   190		return -1
   191	}
   192	
   193	// LastIndexAny returns the index of the last instance of any Unicode code
   194	// point from chars in s, or -1 if no Unicode code point from chars is
   195	// present in s.
   196	func LastIndexAny(s, chars string) int {
   197		if len(chars) > 0 {
   198			if len(s) > 8 {
   199				if as, isASCII := makeASCIISet(chars); isASCII {
   200					for i := len(s) - 1; i >= 0; i-- {
   201						if as.contains(s[i]) {
   202							return i
   203						}
   204					}
   205					return -1
   206				}
   207			}
   208			for i := len(s); i > 0; {
   209				r, size := utf8.DecodeLastRuneInString(s[:i])
   210				i -= size
   211				for _, c := range chars {
   212					if r == c {
   213						return i
   214					}
   215				}
   216			}
   217		}
   218		return -1
   219	}
   220	
   221	// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
   222	func LastIndexByte(s string, c byte) int {
   223		for i := len(s) - 1; i >= 0; i-- {
   224			if s[i] == c {
   225				return i
   226			}
   227		}
   228		return -1
   229	}
   230	
   231	// Generic split: splits after each instance of sep,
   232	// including sepSave bytes of sep in the subarrays.
   233	func genSplit(s, sep string, sepSave, n int) []string {
   234		if n == 0 {
   235			return nil
   236		}
   237		if sep == "" {
   238			return explode(s, n)
   239		}
   240		if n < 0 {
   241			n = Count(s, sep) + 1
   242		}
   243		c := sep[0]
   244		start := 0
   245		a := make([]string, n)
   246		na := 0
   247		for i := 0; i+len(sep) <= len(s) && na+1 < n; i++ {
   248			if s[i] == c && (len(sep) == 1 || s[i:i+len(sep)] == sep) {
   249				a[na] = s[start : i+sepSave]
   250				na++
   251				start = i + len(sep)
   252				i += len(sep) - 1
   253			}
   254		}
   255		a[na] = s[start:]
   256		return a[0 : na+1]
   257	}
   258	
   259	// SplitN slices s into substrings separated by sep and returns a slice of
   260	// the substrings between those separators.
   261	// If sep is empty, SplitN splits after each UTF-8 sequence.
   262	// The count determines the number of substrings to return:
   263	//   n > 0: at most n substrings; the last substring will be the unsplit remainder.
   264	//   n == 0: the result is nil (zero substrings)
   265	//   n < 0: all substrings
   266	func SplitN(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
   267	
   268	// SplitAfterN slices s into substrings after each instance of sep and
   269	// returns a slice of those substrings.
   270	// If sep is empty, SplitAfterN splits after each UTF-8 sequence.
   271	// The count determines the number of substrings to return:
   272	//   n > 0: at most n substrings; the last substring will be the unsplit remainder.
   273	//   n == 0: the result is nil (zero substrings)
   274	//   n < 0: all substrings
   275	func SplitAfterN(s, sep string, n int) []string {
   276		return genSplit(s, sep, len(sep), n)
   277	}
   278	
   279	// Split slices s into all substrings separated by sep and returns a slice of
   280	// the substrings between those separators.
   281	// If sep is empty, Split splits after each UTF-8 sequence.
   282	// It is equivalent to SplitN with a count of -1.
   283	func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }
   284	
   285	// SplitAfter slices s into all substrings after each instance of sep and
   286	// returns a slice of those substrings.
   287	// If sep is empty, SplitAfter splits after each UTF-8 sequence.
   288	// It is equivalent to SplitAfterN with a count of -1.
   289	func SplitAfter(s, sep string) []string {
   290		return genSplit(s, sep, len(sep), -1)
   291	}
   292	
   293	// Fields splits the string s around each instance of one or more consecutive white space
   294	// characters, as defined by unicode.IsSpace, returning an array of substrings of s or an
   295	// empty list if s contains only white space.
   296	func Fields(s string) []string {
   297		return FieldsFunc(s, unicode.IsSpace)
   298	}
   299	
   300	// FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c)
   301	// and returns an array of slices of s. If all code points in s satisfy f(c) or the
   302	// string is empty, an empty slice is returned.
   303	// FieldsFunc makes no guarantees about the order in which it calls f(c).
   304	// If f does not return consistent results for a given c, FieldsFunc may crash.
   305	func FieldsFunc(s string, f func(rune) bool) []string {
   306		// First count the fields.
   307		n := 0
   308		inField := false
   309		for _, rune := range s {
   310			wasInField := inField
   311			inField = !f(rune)
   312			if inField && !wasInField {
   313				n++
   314			}
   315		}
   316	
   317		// Now create them.
   318		a := make([]string, n)
   319		na := 0
   320		fieldStart := -1 // Set to -1 when looking for start of field.
   321		for i, rune := range s {
   322			if f(rune) {
   323				if fieldStart >= 0 {
   324					a[na] = s[fieldStart:i]
   325					na++
   326					fieldStart = -1
   327				}
   328			} else if fieldStart == -1 {
   329				fieldStart = i
   330			}
   331		}
   332		if fieldStart >= 0 { // Last field might end at EOF.
   333			a[na] = s[fieldStart:]
   334		}
   335		return a
   336	}
   337	
   338	// Join concatenates the elements of a to create a single string. The separator string
   339	// sep is placed between elements in the resulting string.
   340	func Join(a []string, sep string) string {
   341		switch len(a) {
   342		case 0:
   343			return ""
   344		case 1:
   345			return a[0]
   346		case 2:
   347			// Special case for common small values.
   348			// Remove if golang.org/issue/6714 is fixed
   349			return a[0] + sep + a[1]
   350		case 3:
   351			// Special case for common small values.
   352			// Remove if golang.org/issue/6714 is fixed
   353			return a[0] + sep + a[1] + sep + a[2]
   354		}
   355		n := len(sep) * (len(a) - 1)
   356		for i := 0; i < len(a); i++ {
   357			n += len(a[i])
   358		}
   359	
   360		b := make([]byte, n)
   361		bp := copy(b, a[0])
   362		for _, s := range a[1:] {
   363			bp += copy(b[bp:], sep)
   364			bp += copy(b[bp:], s)
   365		}
   366		return string(b)
   367	}
   368	
   369	// HasPrefix tests whether the string s begins with prefix.
   370	func HasPrefix(s, prefix string) bool {
   371		return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
   372	}
   373	
   374	// HasSuffix tests whether the string s ends with suffix.
   375	func HasSuffix(s, suffix string) bool {
   376		return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
   377	}
   378	
   379	// Map returns a copy of the string s with all its characters modified
   380	// according to the mapping function. If mapping returns a negative value, the character is
   381	// dropped from the string with no replacement.
   382	func Map(mapping func(rune) rune, s string) string {
   383		// In the worst case, the string can grow when mapped, making
   384		// things unpleasant. But it's so rare we barge in assuming it's
   385		// fine. It could also shrink but that falls out naturally.
   386		maxbytes := len(s) // length of b
   387		nbytes := 0        // number of bytes encoded in b
   388		// The output buffer b is initialized on demand, the first
   389		// time a character differs.
   390		var b []byte
   391	
   392		for i, c := range s {
   393			r := mapping(c)
   394			if b == nil {
   395				if r == c {
   396					continue
   397				}
   398				b = make([]byte, maxbytes)
   399				nbytes = copy(b, s[:i])
   400			}
   401			if r >= 0 {
   402				wid := 1
   403				if r >= utf8.RuneSelf {
   404					wid = utf8.RuneLen(r)
   405				}
   406				if nbytes+wid > maxbytes {
   407					// Grow the buffer.
   408					maxbytes = maxbytes*2 + utf8.UTFMax
   409					nb := make([]byte, maxbytes)
   410					copy(nb, b[0:nbytes])
   411					b = nb
   412				}
   413				nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)
   414			}
   415		}
   416		if b == nil {
   417			return s
   418		}
   419		return string(b[0:nbytes])
   420	}
   421	
   422	// Repeat returns a new string consisting of count copies of the string s.
   423	//
   424	// It panics if count is negative or if
   425	// the result of (len(s) * count) overflows.
   426	func Repeat(s string, count int) string {
   427		// Since we cannot return an error on overflow,
   428		// we should panic if the repeat will generate
   429		// an overflow.
   430		// See Issue golang.org/issue/16237
   431		if count < 0 {
   432			panic("strings: negative Repeat count")
   433		} else if count > 0 && len(s)*count/count != len(s) {
   434			panic("strings: Repeat count causes overflow")
   435		}
   436	
   437		b := make([]byte, len(s)*count)
   438		bp := copy(b, s)
   439		for bp < len(b) {
   440			copy(b[bp:], b[:bp])
   441			bp *= 2
   442		}
   443		return string(b)
   444	}
   445	
   446	// ToUpper returns a copy of the string s with all Unicode letters mapped to their upper case.
   447	func ToUpper(s string) string { return Map(unicode.ToUpper, s) }
   448	
   449	// ToLower returns a copy of the string s with all Unicode letters mapped to their lower case.
   450	func ToLower(s string) string { return Map(unicode.ToLower, s) }
   451	
   452	// ToTitle returns a copy of the string s with all Unicode letters mapped to their title case.
   453	func ToTitle(s string) string { return Map(unicode.ToTitle, s) }
   454	
   455	// ToUpperSpecial returns a copy of the string s with all Unicode letters mapped to their
   456	// upper case, giving priority to the special casing rules.
   457	func ToUpperSpecial(c unicode.SpecialCase, s string) string {
   458		return Map(func(r rune) rune { return c.ToUpper(r) }, s)
   459	}
   460	
   461	// ToLowerSpecial returns a copy of the string s with all Unicode letters mapped to their
   462	// lower case, giving priority to the special casing rules.
   463	func ToLowerSpecial(c unicode.SpecialCase, s string) string {
   464		return Map(func(r rune) rune { return c.ToLower(r) }, s)
   465	}
   466	
   467	// ToTitleSpecial returns a copy of the string s with all Unicode letters mapped to their
   468	// title case, giving priority to the special casing rules.
   469	func ToTitleSpecial(c unicode.SpecialCase, s string) string {
   470		return Map(func(r rune) rune { return c.ToTitle(r) }, s)
   471	}
   472	
   473	// isSeparator reports whether the rune could mark a word boundary.
   474	// TODO: update when package unicode captures more of the properties.
   475	func isSeparator(r rune) bool {
   476		// ASCII alphanumerics and underscore are not separators
   477		if r <= 0x7F {
   478			switch {
   479			case '0' <= r && r <= '9':
   480				return false
   481			case 'a' <= r && r <= 'z':
   482				return false
   483			case 'A' <= r && r <= 'Z':
   484				return false
   485			case r == '_':
   486				return false
   487			}
   488			return true
   489		}
   490		// Letters and digits are not separators
   491		if unicode.IsLetter(r) || unicode.IsDigit(r) {
   492			return false
   493		}
   494		// Otherwise, all we can do for now is treat spaces as separators.
   495		return unicode.IsSpace(r)
   496	}
   497	
   498	// Title returns a copy of the string s with all Unicode letters that begin words
   499	// mapped to their title case.
   500	//
   501	// BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
   502	func Title(s string) string {
   503		// Use a closure here to remember state.
   504		// Hackish but effective. Depends on Map scanning in order and calling
   505		// the closure once per rune.
   506		prev := ' '
   507		return Map(
   508			func(r rune) rune {
   509				if isSeparator(prev) {
   510					prev = r
   511					return unicode.ToTitle(r)
   512				}
   513				prev = r
   514				return r
   515			},
   516			s)
   517	}
   518	
   519	// TrimLeftFunc returns a slice of the string s with all leading
   520	// Unicode code points c satisfying f(c) removed.
   521	func TrimLeftFunc(s string, f func(rune) bool) string {
   522		i := indexFunc(s, f, false)
   523		if i == -1 {
   524			return ""
   525		}
   526		return s[i:]
   527	}
   528	
   529	// TrimRightFunc returns a slice of the string s with all trailing
   530	// Unicode code points c satisfying f(c) removed.
   531	func TrimRightFunc(s string, f func(rune) bool) string {
   532		i := lastIndexFunc(s, f, false)
   533		if i >= 0 && s[i] >= utf8.RuneSelf {
   534			_, wid := utf8.DecodeRuneInString(s[i:])
   535			i += wid
   536		} else {
   537			i++
   538		}
   539		return s[0:i]
   540	}
   541	
   542	// TrimFunc returns a slice of the string s with all leading
   543	// and trailing Unicode code points c satisfying f(c) removed.
   544	func TrimFunc(s string, f func(rune) bool) string {
   545		return TrimRightFunc(TrimLeftFunc(s, f), f)
   546	}
   547	
   548	// IndexFunc returns the index into s of the first Unicode
   549	// code point satisfying f(c), or -1 if none do.
   550	func IndexFunc(s string, f func(rune) bool) int {
   551		return indexFunc(s, f, true)
   552	}
   553	
   554	// LastIndexFunc returns the index into s of the last
   555	// Unicode code point satisfying f(c), or -1 if none do.
   556	func LastIndexFunc(s string, f func(rune) bool) int {
   557		return lastIndexFunc(s, f, true)
   558	}
   559	
   560	// indexFunc is the same as IndexFunc except that if
   561	// truth==false, the sense of the predicate function is
   562	// inverted.
   563	func indexFunc(s string, f func(rune) bool, truth bool) int {
   564		start := 0
   565		for start < len(s) {
   566			wid := 1
   567			r := rune(s[start])
   568			if r >= utf8.RuneSelf {
   569				r, wid = utf8.DecodeRuneInString(s[start:])
   570			}
   571			if f(r) == truth {
   572				return start
   573			}
   574			start += wid
   575		}
   576		return -1
   577	}
   578	
   579	// lastIndexFunc is the same as LastIndexFunc except that if
   580	// truth==false, the sense of the predicate function is
   581	// inverted.
   582	func lastIndexFunc(s string, f func(rune) bool, truth bool) int {
   583		for i := len(s); i > 0; {
   584			r, size := utf8.DecodeLastRuneInString(s[0:i])
   585			i -= size
   586			if f(r) == truth {
   587				return i
   588			}
   589		}
   590		return -1
   591	}
   592	
   593	// asciiSet is a 32-byte value, where each bit represents the presence of a
   594	// given ASCII character in the set. The 128-bits of the lower 16 bytes,
   595	// starting with the least-significant bit of the lowest word to the
   596	// most-significant bit of the highest word, map to the full range of all
   597	// 128 ASCII characters. The 128-bits of the upper 16 bytes will be zeroed,
   598	// ensuring that any non-ASCII character will be reported as not in the set.
   599	type asciiSet [8]uint32
   600	
   601	// makeASCIISet creates a set of ASCII characters and reports whether all
   602	// characters in chars are ASCII.
   603	func makeASCIISet(chars string) (as asciiSet, ok bool) {
   604		for i := 0; i < len(chars); i++ {
   605			c := chars[i]
   606			if c >= utf8.RuneSelf {
   607				return as, false
   608			}
   609			as[c>>5] |= 1 << uint(c&31)
   610		}
   611		return as, true
   612	}
   613	
   614	// contains reports whether c is inside the set.
   615	func (as *asciiSet) contains(c byte) bool {
   616		return (as[c>>5] & (1 << uint(c&31))) != 0
   617	}
   618	
   619	func makeCutsetFunc(cutset string) func(rune) bool {
   620		if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
   621			return func(r rune) bool {
   622				return r == rune(cutset[0])
   623			}
   624		}
   625		if as, isASCII := makeASCIISet(cutset); isASCII {
   626			return func(r rune) bool {
   627				return r < utf8.RuneSelf && as.contains(byte(r))
   628			}
   629		}
   630		return func(r rune) bool { return IndexRune(cutset, r) >= 0 }
   631	}
   632	
   633	// Trim returns a slice of the string s with all leading and
   634	// trailing Unicode code points contained in cutset removed.
   635	func Trim(s string, cutset string) string {
   636		if s == "" || cutset == "" {
   637			return s
   638		}
   639		return TrimFunc(s, makeCutsetFunc(cutset))
   640	}
   641	
   642	// TrimLeft returns a slice of the string s with all leading
   643	// Unicode code points contained in cutset removed.
   644	func TrimLeft(s string, cutset string) string {
   645		if s == "" || cutset == "" {
   646			return s
   647		}
   648		return TrimLeftFunc(s, makeCutsetFunc(cutset))
   649	}
   650	
   651	// TrimRight returns a slice of the string s, with all trailing
   652	// Unicode code points contained in cutset removed.
   653	func TrimRight(s string, cutset string) string {
   654		if s == "" || cutset == "" {
   655			return s
   656		}
   657		return TrimRightFunc(s, makeCutsetFunc(cutset))
   658	}
   659	
   660	// TrimSpace returns a slice of the string s, with all leading
   661	// and trailing white space removed, as defined by Unicode.
   662	func TrimSpace(s string) string {
   663		return TrimFunc(s, unicode.IsSpace)
   664	}
   665	
   666	// TrimPrefix returns s without the provided leading prefix string.
   667	// If s doesn't start with prefix, s is returned unchanged.
   668	func TrimPrefix(s, prefix string) string {
   669		if HasPrefix(s, prefix) {
   670			return s[len(prefix):]
   671		}
   672		return s
   673	}
   674	
   675	// TrimSuffix returns s without the provided trailing suffix string.
   676	// If s doesn't end with suffix, s is returned unchanged.
   677	func TrimSuffix(s, suffix string) string {
   678		if HasSuffix(s, suffix) {
   679			return s[:len(s)-len(suffix)]
   680		}
   681		return s
   682	}
   683	
   684	// Replace returns a copy of the string s with the first n
   685	// non-overlapping instances of old replaced by new.
   686	// If old is empty, it matches at the beginning of the string
   687	// and after each UTF-8 sequence, yielding up to k+1 replacements
   688	// for a k-rune string.
   689	// If n < 0, there is no limit on the number of replacements.
   690	func Replace(s, old, new string, n int) string {
   691		if old == new || n == 0 {
   692			return s // avoid allocation
   693		}
   694	
   695		// Compute number of replacements.
   696		if m := Count(s, old); m == 0 {
   697			return s // avoid allocation
   698		} else if n < 0 || m < n {
   699			n = m
   700		}
   701	
   702		// Apply replacements to buffer.
   703		t := make([]byte, len(s)+n*(len(new)-len(old)))
   704		w := 0
   705		start := 0
   706		for i := 0; i < n; i++ {
   707			j := start
   708			if len(old) == 0 {
   709				if i > 0 {
   710					_, wid := utf8.DecodeRuneInString(s[start:])
   711					j += wid
   712				}
   713			} else {
   714				j += Index(s[start:], old)
   715			}
   716			w += copy(t[w:], s[start:j])
   717			w += copy(t[w:], new)
   718			start = j + len(old)
   719		}
   720		w += copy(t[w:], s[start:])
   721		return string(t[0:w])
   722	}
   723	
   724	// EqualFold reports whether s and t, interpreted as UTF-8 strings,
   725	// are equal under Unicode case-folding.
   726	func EqualFold(s, t string) bool {
   727		for s != "" && t != "" {
   728			// Extract first rune from each string.
   729			var sr, tr rune
   730			if s[0] < utf8.RuneSelf {
   731				sr, s = rune(s[0]), s[1:]
   732			} else {
   733				r, size := utf8.DecodeRuneInString(s)
   734				sr, s = r, s[size:]
   735			}
   736			if t[0] < utf8.RuneSelf {
   737				tr, t = rune(t[0]), t[1:]
   738			} else {
   739				r, size := utf8.DecodeRuneInString(t)
   740				tr, t = r, t[size:]
   741			}
   742	
   743			// If they match, keep going; if not, return false.
   744	
   745			// Easy case.
   746			if tr == sr {
   747				continue
   748			}
   749	
   750			// Make sr < tr to simplify what follows.
   751			if tr < sr {
   752				tr, sr = sr, tr
   753			}
   754			// Fast check for ASCII.
   755			if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
   756				// ASCII, and sr is upper case.  tr must be lower case.
   757				if tr == sr+'a'-'A' {
   758					continue
   759				}
   760				return false
   761			}
   762	
   763			// General case. SimpleFold(x) returns the next equivalent rune > x
   764			// or wraps around to smaller values.
   765			r := unicode.SimpleFold(sr)
   766			for r != sr && r < tr {
   767				r = unicode.SimpleFold(r)
   768			}
   769			if r == tr {
   770				continue
   771			}
   772			return false
   773		}
   774	
   775		// One string is empty. Are both?
   776		return s == t
   777	}
   778	

View as plain text