fix Replacer suffix match, and add test case (#2867)
* fix: replace shoud replace the longest match * feat: revert bytes.Buffer to strings.Builder * fix: loop reset nextStart * feat: add node longest match test * feat: add replacer suffix match test case * feat: multiple match * fix: partial match ends * fix: replace look back upon error * feat: rm unnecessary branch --------- Co-authored-by: hudahai <hscxrzs@gmail.com> Co-authored-by: hushichang <hushichang@sensetime.com>
This commit is contained in:
@@ -33,29 +33,26 @@ func NewReplacer(mapping map[string]string) Replacer {
|
||||
// Replace replaces text with given substitutes.
|
||||
func (r *replacer) Replace(text string) string {
|
||||
var buf strings.Builder
|
||||
var nextStart int
|
||||
target := []rune(text)
|
||||
cur := r.node
|
||||
|
||||
var paths []*node
|
||||
for len(target) != 0 {
|
||||
used, jump, matched := cur.longestMatch(target, nextStart)
|
||||
if matched {
|
||||
replaced := r.mapping[string(target[:used])]
|
||||
target = append([]rune(replaced), target[used:]...)
|
||||
cur = r.node
|
||||
nextStart = 0
|
||||
uselessLen, matchLen, nextPaths := cur.longestMatch(target, paths)
|
||||
if uselessLen > 0 {
|
||||
buf.WriteString(string(target[:uselessLen]))
|
||||
target = target[uselessLen:]
|
||||
}
|
||||
if matchLen > 0 {
|
||||
replaced := r.mapping[string(target[:matchLen])]
|
||||
target = append([]rune(replaced), target[matchLen:]...)
|
||||
}
|
||||
if len(nextPaths) != 0 {
|
||||
cur = nextPaths[len(nextPaths)-1]
|
||||
paths = nextPaths
|
||||
} else {
|
||||
buf.WriteString(string(target[:used]))
|
||||
target = target[used:]
|
||||
if jump != nil {
|
||||
cur = jump
|
||||
nextStart = jump.depth
|
||||
} else {
|
||||
cur = r.node
|
||||
nextStart = 0
|
||||
}
|
||||
cur = r.node
|
||||
paths = nil
|
||||
}
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user