replacer.go 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. mapping: mapping,
  17. }
  18. for k := range mapping {
  19. rep.add(k)
  20. }
  21. return rep
  22. }
  23. func (r *replacer) Replace(text string) string {
  24. var builder strings.Builder
  25. chars := []rune(text)
  26. size := len(chars)
  27. start := -1
  28. for i := 0; i < size; i++ {
  29. child, ok := r.children[chars[i]]
  30. if !ok {
  31. builder.WriteRune(chars[i])
  32. continue
  33. }
  34. if start < 0 {
  35. start = i
  36. }
  37. end := -1
  38. if child.end {
  39. end = i + 1
  40. }
  41. j := i + 1
  42. for ; j < size; j++ {
  43. grandchild, ok := child.children[chars[j]]
  44. if !ok {
  45. break
  46. }
  47. child = grandchild
  48. if child.end {
  49. end = j + 1
  50. i = j
  51. }
  52. }
  53. if end > 0 {
  54. i = j - 1
  55. builder.WriteString(r.mapping[string(chars[start:end])])
  56. } else {
  57. builder.WriteRune(chars[i])
  58. }
  59. start = -1
  60. }
  61. return builder.String()
  62. }