string.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package stringx
  2. import (
  3. "bytes"
  4. "strings"
  5. "unicode"
  6. "golang.org/x/text/cases"
  7. "golang.org/x/text/language"
  8. )
  9. var WhiteSpace = []rune{'\n', '\t', '\f', '\v', ' '}
  10. // String provides for converting the source text into other spell case,like lower,snake,camel
  11. type String struct {
  12. source string
  13. }
  14. // From converts the input text to String and returns it
  15. func From(data string) String {
  16. return String{source: data}
  17. }
  18. // IsEmptyOrSpace returns true if the length of the string value is 0 after call strings.TrimSpace, or else returns false
  19. func (s String) IsEmptyOrSpace() bool {
  20. if len(s.source) == 0 {
  21. return true
  22. }
  23. if strings.TrimSpace(s.source) == "" {
  24. return true
  25. }
  26. return false
  27. }
  28. // Lower calls the strings.ToLower
  29. func (s String) Lower() string {
  30. return strings.ToLower(s.source)
  31. }
  32. // Upper calls the strings.ToUpper
  33. func (s String) Upper() string {
  34. return strings.ToUpper(s.source)
  35. }
  36. // ReplaceAll calls the strings.ReplaceAll
  37. func (s String) ReplaceAll(old, new string) string {
  38. return strings.Replace(s.source, old, new, -1)
  39. }
  40. // Source returns the source string value
  41. func (s String) Source() string {
  42. return s.source
  43. }
  44. // Title calls the cases.Title
  45. func (s String) Title() string {
  46. if s.IsEmptyOrSpace() {
  47. return s.source
  48. }
  49. return cases.Title(language.English).String(s.source)
  50. }
  51. // ToCamel converts the input text into camel case
  52. func (s String) ToCamel() string {
  53. list := s.splitBy(func(r rune) bool {
  54. return r == '_'
  55. }, true)
  56. var target []string
  57. for _, item := range list {
  58. target = append(target, From(item).Title())
  59. }
  60. return strings.Join(target, "")
  61. }
  62. // ToSnake converts the input text into snake case
  63. func (s String) ToSnake() string {
  64. list := s.splitBy(unicode.IsUpper, false)
  65. var target []string
  66. for _, item := range list {
  67. target = append(target, From(item).Lower())
  68. }
  69. return strings.Join(target, "_")
  70. }
  71. // Untitle return the original string if rune is not letter at index 0
  72. func (s String) Untitle() string {
  73. if s.IsEmptyOrSpace() {
  74. return s.source
  75. }
  76. r := rune(s.source[0])
  77. if !unicode.IsUpper(r) && !unicode.IsLower(r) {
  78. return s.source
  79. }
  80. return string(unicode.ToLower(r)) + s.source[1:]
  81. }
  82. // it will not ignore spaces
  83. func (s String) splitBy(fn func(r rune) bool, remove bool) []string {
  84. if s.IsEmptyOrSpace() {
  85. return nil
  86. }
  87. var list []string
  88. buffer := new(bytes.Buffer)
  89. for _, r := range s.source {
  90. if fn(r) {
  91. if buffer.Len() != 0 {
  92. list = append(list, buffer.String())
  93. buffer.Reset()
  94. }
  95. if !remove {
  96. buffer.WriteRune(r)
  97. }
  98. continue
  99. }
  100. buffer.WriteRune(r)
  101. }
  102. if buffer.Len() != 0 {
  103. list = append(list, buffer.String())
  104. }
  105. return list
  106. }
  107. func ContainsAny(s string, runes ...rune) bool {
  108. if len(runes) == 0 {
  109. return true
  110. }
  111. tmp := make(map[rune]struct{}, len(runes))
  112. for _, r := range runes {
  113. tmp[r] = struct{}{}
  114. }
  115. for _, r := range s {
  116. if _, ok := tmp[r]; ok {
  117. return true
  118. }
  119. }
  120. return false
  121. }
  122. func ContainsWhiteSpace(s string) bool {
  123. return ContainsAny(s, WhiteSpace...)
  124. }