为了账号安全,请及时绑定邮箱和手机立即绑定

在不使用正则表达式的情况下替换整个单词

在不使用正则表达式的情况下替换整个单词

Go
慕慕森 2022-05-18 15:47:10
我正在使用string.Replace替换子字符串Afunc removeIP(text string) string {    text = strings.Replace(text, "someWord", "**NewWord**", -1)    return text}func removeIPUsingRegex(text string) string {    var re = regexp.MustCompile(`\b` + "someWord" + `\b`) // I want to replace whole word only    text = re.ReplaceAllString(text, "**NewWord**")}我在这里面临的问题是,只有在字符串替换不支持的情况下,我才想替换整个单词。因为我必须替换非常非常大的字符串,所以可能以 GB 为单位。与字符串替换相比,正则表达式非常慢。eg: text: "abcdef defgh /def/ .def/ =def= def xxxy"-> Replace defwith DEFoutput: "abcdef defgh /DEF/ .DEF/ =DEF= DEF xxxy"//注意只有整个单词被替换了。正则表达式将时间缩短了近 100 倍(https://medium.com/codezillas/golang-replace-vs-regexp-de4e48482f53)。任何想法将不胜感激。
查看完整描述

1 回答

?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

使用的 KMP 算法

// ReplaceWholeWord ...


 func ReplaceWholeWord(text string, oldWord string, newWord string) string {

        var patternLength = len(oldWord)

        var textLength = len(text) 


        var copyIndex = 0

        var textIndex = 0

        var patternIndex = 0

        var newString strings.Builder

        var lps = computeLPSArray(oldWord)


        for textIndex < textLength {

            if oldWord[patternIndex] == text[textIndex] {

                patternIndex++

                textIndex++

            }

            if patternIndex == patternLength {

                startIndex := textIndex - patternIndex

                endIndex := textIndex - patternIndex + patternLength - 1


                if checkIfWholeWord(text, startIndex, endIndex) {

                    if copyIndex != startIndex {

                        newString.WriteString(text[copyIndex:startIndex])

                    }

                    newString.WriteString(newWord)

                    copyIndex = endIndex + 1

                }


                patternIndex = 0

                textIndex = endIndex + 1


            } else if textIndex < textLength && oldWord[patternIndex] != text[textIndex] {


                if patternIndex != 0 {

                    patternIndex = lps[patternIndex-1]


                } else {

                    textIndex = textIndex + 1

                }


            }

        }

        newString.WriteString(text[copyIndex:])


        return newString.String()

    }


    func computeLPSArray(pattern string) []int {

        var length = 0

        var i = 1

        var patternLength = len(pattern)


        var lps = make([]int, patternLength)


        lps[0] = 0


        for i = 1; i < patternLength; {

            if pattern[i] == pattern[length] {

                length++

                lps[i] = length

                i++


            } else {


                if length != 0 {

                    length = lps[length-1]


                } else {

                    lps[i] = length

                    i++

                }

            }

        }

        return lps

    }


    func checkIfWholeWord(text string, startIndex int, endIndex int) bool {

        startIndex = startIndex - 1

        endIndex = endIndex + 1


        if (startIndex < 0 && endIndex >= len(text)) ||

            (startIndex < 0 && endIndex < len(text) && isNonWord(text[endIndex])) ||

            (startIndex >= 0 && endIndex >= len(text) && isNonWord(text[startIndex])) ||

            (startIndex >= 0 && endIndex < len(text) && isNonWord(text[startIndex]) && isNonWord(text[endIndex])) {

            return true

        }


        return false

    }


    func isNonWord(c byte) bool {

        return !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'))

    }


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 81 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信