登录
首页 >  Golang >  Go问答

不使用正则表达式替换整个单词

来源:stackoverflow

时间:2024-04-06 23:45:36 457浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《不使用正则表达式替换整个单词》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

问题内容

我正在使用 string.replace 替换子字符串 a

func 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 为单位。与字符串替换相比,正则表达式非常慢。

例如:文本:"abcdef defgh /def/ .def/ =def= def xxxy" -> 将 def 替换为 def

输出: "abcdef defgh /def/ .def/ =def= def xxxy" //注意只有整个单词被替换。

正则表达式将时间缩短了近 100 倍 (https://medium.com/codezillas/golang-replace-vs-regexp-de4e48482f53)。任何想法将不胜感激。


解决方案


使用的 kmp 算法
// 替换整个单词...

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 == '_'))
    }

今天关于《不使用正则表达式替换整个单词》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>