replacer.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package stringx
  2. import "strings"
  3. type (
  4. Replacer interface {
  5. Replace(text string) string
  6. }
  7. replacer struct {
  8. node
  9. mapping map[string]string
  10. }
  11. )
  12. func NewReplacer(mapping map[string]string) Replacer {
  13. var rep = &replacer{
  14. mapping: mapping,
  15. }
  16. for k := range mapping {
  17. rep.add(k)
  18. }
  19. return rep
  20. }
  21. func (r *replacer) Replace(text string) string {
  22. var builder strings.Builder
  23. var chars = []rune(text)
  24. var size = len(chars)
  25. var start = -1
  26. for i := 0; i < size; i++ {
  27. child, ok := r.children[chars[i]]
  28. if !ok {
  29. builder.WriteRune(chars[i])
  30. continue
  31. }
  32. if start < 0 {
  33. start = i
  34. }
  35. var end = -1
  36. if child.end {
  37. end = i + 1
  38. }
  39. var j = i + 1
  40. for ; j < size; j++ {
  41. grandchild, ok := child.children[chars[j]]
  42. if !ok {
  43. break
  44. }
  45. child = grandchild
  46. if child.end {
  47. end = j + 1
  48. i = j
  49. }
  50. }
  51. if end > 0 {
  52. i = j - 1
  53. builder.WriteString(r.mapping[string(chars[start:end])])
  54. } else {
  55. builder.WriteRune(chars[i])
  56. }
  57. start = -1
  58. }
  59. return builder.String()
  60. }