go改写Apache Commons StringUtils中的replaceEach方法
在实习过程中,碰到了一个需要将string字符串按照一定规则,例如“同学泥好”字符串需按照{“泥”:“你”}进行替换,在此过程中只需要简单的使用go中的***strings.ReplaceAll()***方法就可实现。
但在复杂逻辑中,例如字符串= “你好夏天”,映射表 = {“你”: “尼”, “尼好”: “你好”} ,可能会出现覆盖已替换结果的情况。这时候我查看strings包里的替换方法只有两个,一个是replace(),另一个是replaceAll()
这个时候就需要我们自己实现这个逻辑。但是java中有现成的方法将其实现,Apache Commons StringUtils中的replaceEach()。有兴趣可以自己看下源码。于是我将此方法用go改写了一下,供大家参看。
func replaceEach(text string, Mapping map[string]string) string {
var searchList []string
var replacementList []string
// 将Mapping转为list
for k, v := range Mapping {
searchList = append(searchList, k)
replacementList = append(replacementList, v)
}
var searchLength = len(searchList)
var noMoreMatchesForReplIndex []bool
for i := 0; i < searchLength; i++ {
noMoreMatchesForReplIndex = append(noMoreMatchesForReplIndex, false)
}
// index on index that the match was found
var (
textIndex = -1
replaceIndex = -1
tempIndex = -1
)
// 搜索待替换字符串replacementList中所有元素在text最前面的索引
for i := 0; i < searchLength; i++ {
if noMoreMatchesForReplIndex[i] {
continue
}
tempIndex = strings.Index(text, searchList[i])
// see if we need to keep searching for this
if tempIndex == -1 {
noMoreMatchesForReplIndex[i] = true
} else {
if textIndex == -1 || tempIndex < textIndex {
textIndex = tempIndex
replaceIndex = i
}
}
}
if textIndex == -1 {
return text
}
var (
start = 0
buf strings.Builder
)
for textIndex != -1 {
// 将需要要替换的字符串前面的字符串追加到buf里面
buf.WriteString(text[start:textIndex])
// buf加入需要替换的字符串
buf.WriteString(replacementList[replaceIndex])
//将start指针延后被替换掉的字符串的长度
start = textIndex + len(searchList[replaceIndex])
textIndex = -1
replaceIndex = -1
tempIndex = -1
// find the next earliest match
// NOTE: logic mostly duplicated above START
for i := 0; i < searchLength; i++ {
if noMoreMatchesForReplIndex[i] {
continue
}
tempIndex = strings.Index(text[start:], searchList[i])
// see if we need to keep searching for this
if tempIndex == -1 {
noMoreMatchesForReplIndex[i] = true
} else {
tempIndex = start + tempIndex
if textIndex == -1 || tempIndex < textIndex {
textIndex = tempIndex
replaceIndex = i
}
}
}
}
buf.WriteString(text[start:])
return buf.String()
}