replacer.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package stringx
  2. import "strings"
  3. type (
  4. // Replacer interface wraps the Replace method.
  5. Replacer interface {
  6. Replace(text string) string
  7. }
  8. replacer struct {
  9. *node
  10. mapping map[string]string
  11. }
  12. )
  13. // NewReplacer returns a Replacer.
  14. func NewReplacer(mapping map[string]string) Replacer {
  15. rep := &replacer{
  16. node: new(node),
  17. mapping: mapping,
  18. }
  19. for k := range mapping {
  20. rep.add(k)
  21. }
  22. rep.build()
  23. return rep
  24. }
  25. // Replace replaces text with given substitutes.
  26. func (r *replacer) Replace(text string) string {
  27. var buf strings.Builder
  28. target := []rune(text)
  29. cur := r.node
  30. nextStart := 0
  31. for len(target) != 0 {
  32. used, jump, matched := cur.longestMatch(target, nextStart)
  33. if matched {
  34. replaced := r.mapping[string(target[:used])]
  35. target = append([]rune(replaced), target[used:]...)
  36. cur = r.node
  37. nextStart = 0
  38. } else {
  39. buf.WriteString(string(target[:used]))
  40. target = target[used:]
  41. if jump != nil {
  42. cur = jump
  43. nextStart = jump.depth
  44. } else {
  45. cur = r.node
  46. nextStart = 0
  47. }
  48. }
  49. }
  50. return buf.String()
  51. }