程序笔记   发布时间:2022-07-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了NewReplacer使用技巧大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

原文链接:http://www.zhoubotong.site/post/34.html

        上次写博客至今有段时间了,这些日子,认真过,努力过,职场中不管有哪些让人失意或不快的事,终归到底,是自己不够强大。。。

好吧,新的一年,不磨磨唧唧了,一般处理xss漏洞使用正则匹配,再次分享一个golang Strings包Newreplacer的方法。

我们先看一个简单的例子

@H_450_8@
package main

import (
    "fmt"
    "Strings"
)

func main() {
    var str= Strings.Newreplacer("Hello", "HelLO", "鸠摩智", "老鸠")
    s1 := str.replace("Hello")
    s2 := str.replace("鸠摩智")
    fmt.Println(s1, s2)
}
//输出 HelLO 老鸠

通过上面的输出大家应该明眼看出来了。我们看下底层相关函数的应用:

@H_450_8@
// replacer replaces a list of Strings with replacements.
// it is safe for concurrent use by multiple goroutInes.
type replacer struct {
    once   sync.once // guards buildOnce method
    r      replacer
    oldnew []String
}

// Newreplacer panics if given an odd number of arguments.
func Newreplacer(oldnew ...String) *replacer {
    if len(oldnew)%2 == 1 {
        panic("Strings.Newreplacer: odd argument count")
    }
    return &replacer{oldnew: append([]String(nil), oldnew...)}
}

// replace returns a copy of s with all replacements performed.
func (r *replacer) replace(s String) String {
    r.once.Do(r.buildOncE)
    return r.r.replace(s)
}

代码分析

Newreplacer() 使用提供的多组old=>new的字符串,创建并返回一个*replacer替换程序的指针,replace() 是返回s的所有替换进行完成后的一个拷贝。

@H_450_8@即Strings.Newreplacer()是 Golang中的函数从以前的新字符串集列表中返回了新的replacer。

我们再看个例子:

@H_450_8@
package main

import (
    "fmt"
    "Strings"
)

func main() {
    r := Strings.Newreplacer("?", "?", ">", ">")
    fmt.Println(r.replace("just do it ?, one -> two"))
    // 试下这里输出啥 fmt.Println(r.replace("鸠摩智")) 
}
//原样输出 just do it ?, one -> two

很容易理解,是吧?这里再说明下一个小注意事项:

替换是按照它们在目标字符串中显示的顺序进行,没有重叠的匹配项。旧的字符串比较按参数顺序进行。神马个意思?

存在重复替换字节

既然是替换,我们肯定也会好奇如果是用重复替换项例如("a","A","a","B")GO会如何处理?

@H_450_8@
package main

import (
    "fmt"
    "Strings"
)

func main() {
    var str1 = Strings.Newreplacer("a", "A", "a", "B") // 前面 a->A, 后面a=>B
    s1 := str1.replace("abc")                          // 一个个字符匹配吧
    fmt.Println(s1)                                    //Abc

    var str2 = Strings.Newreplacer("a", "B", "a", "A")
    s2 := str2.replace("abc")
    fmt.Println(s2) //Bbc

    var str3 = Strings.Newreplacer("李莫愁", "小李", "李莫愁", "小李子")
    s3 := str3.replace("你莫愁啊,不是李莫愁,像是李莫愁")
    fmt.Println(s3)
}
//Abc
//Bbc
//你莫愁啊,不是小李,像是小李

通过上面的测试实例,大家应该发现GO在处理过程中会按照第一次的替换规则为准,也就是匹配规则不覆盖。为了确定 我们看下GO相关部分的源码:

@H_450_8@
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
    }

    r := byteStringreplacer{toreplace: make([]String, 0, len(oldnew)/2)}
    // 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]
        // To avoid counTing repetitions multiple times.
        if r.replacements[o] == nil {
            // We need to use String([]byte{o}) instead of String(o),
            // to avoid utf8 encoding of o.
            // E. g. byte(150) produces String of length 2.
            r.toreplace = append(r.toreplace, String([]byte{o}))
        }
        r.replacements[o] = []byte(n)

    }
    return &r
}

最后特别提醒:如果给定奇数个参数,请记住Newreplacer会抛出panic。

  

  

  

大佬总结

以上是大佬教程为你收集整理的NewReplacer使用技巧全部内容,希望文章能够帮你解决NewReplacer使用技巧所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:listmapphp参数源码程序员职场
猜你在找的程序笔记相关文章
其他相关热搜词更多
phpJavaPython程序员load如何string使用参数jquery开发安装listlinuxiosandroid工具javascriptcap