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:
dahaihu
2023-02-12 21:04:35 +08:00
committed by GitHub
parent 3736dacf1e
commit cacd5dc91a
4 changed files with 349 additions and 49 deletions

View File

@@ -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()
}