相关方法的声明
func NewReplacer(oldnew ...string) *Replacer
func (r *Replacer) Replace(s string) string
func (r *Replacer) WriteString(w io.Writer, s string) (n int, err error)
方法的作用
NewReplacer() 使用提供的多组old、new字符串对创建并返回一个*Replacer
Replace() 返回s的所有替换进行完后的拷贝。
WriteString向w中写入s的所有替换进行完后的拷贝。
简单实例
var test = strings.NewReplacer("a", "A", "b", "B")
s := test.Replace("acpbsf")
fmt.Println(s) //AcpBsf
通过测试发现字符串中的a,b替换成了相应的大写A,B
存在重复替换字节的实例
既然是替换,我们肯定也会好奇如果是用重复替换项例如("a","A","a","B")GO会如何处理
var test1 = strings.NewReplacer("a", "A", "a", "B")
s1 := test1.Replace("abc")
fmt.Println(s1) //Abc
var test2 = strings.NewReplacer("a", "B", "a", "A")
s2 := test2.Replace("abc")
fmt.Println(s2) //Bbc
通过测试实例 我们发现GO在处理过程中会按照第一次的替换规则为准,也就是匹配规则不覆盖。为了确定 我们看下GO相关部分的源码
//构建替换项
func (b *Replacer) build() replacer {
oldnew := b.oldnew
if len(oldnew) == 2 && len(oldnew[0]) > 1 {
return makeSingleStringReplacer(oldnew[0], oldnew[1])
}
allNewBytes := true
for i := 0; i < len(oldnew); i += 2 {
if len(oldnew[i]) != 1 {
return makeGenericReplacer(oldnew)
}
if len(oldnew[i+1]) != 1 {
allNewBytes = false
}
}
//如果都是字节替换,会进入这个if条件
if allNewBytes {
r := byteReplacer{}
for i := range r {
r[i] = byte(i)
}
// The first occurrence of old->new map takes precedence
// over the others with the same old string.
//这里就是我们需要的地方,通过这个循环我们发现替换规则是倒叙生成的
//重复的靠前的会覆盖靠后的
for i := len(oldnew) - 2; i >= 0; i -= 2 {
o := oldnew[i][0]
n := oldnew[i+1][0]
r[o] = n
}
return &r
}
//后续代码
}