/vendor/github.com/asaskevich/govalidator/utils.go

https://gitlab.com/unofficial-mirrors/kubernetes · Go · 213 lines · 160 code · 22 blank · 31 comment · 33 complexity · e0948e2ca686c941cc32afbded818706 MD5 · raw file

  1. package govalidator
  2. import (
  3. "errors"
  4. "fmt"
  5. "html"
  6. "path"
  7. "regexp"
  8. "strings"
  9. "unicode"
  10. )
  11. // Contains check if the string contains the substring.
  12. func Contains(str, substring string) bool {
  13. return strings.Contains(str, substring)
  14. }
  15. // Matches check if string matches the pattern (pattern is regular expression)
  16. // In case of error return false
  17. func Matches(str, pattern string) bool {
  18. match, _ := regexp.MatchString(pattern, str)
  19. return match
  20. }
  21. // LeftTrim trim characters from the left-side of the input.
  22. // If second argument is empty, it's will be remove leading spaces.
  23. func LeftTrim(str, chars string) string {
  24. pattern := ""
  25. if chars == "" {
  26. pattern = "^\\s+"
  27. } else {
  28. pattern = "^[" + chars + "]+"
  29. }
  30. r, _ := regexp.Compile(pattern)
  31. return string(r.ReplaceAll([]byte(str), []byte("")))
  32. }
  33. // RightTrim trim characters from the right-side of the input.
  34. // If second argument is empty, it's will be remove spaces.
  35. func RightTrim(str, chars string) string {
  36. pattern := ""
  37. if chars == "" {
  38. pattern = "\\s+$"
  39. } else {
  40. pattern = "[" + chars + "]+$"
  41. }
  42. r, _ := regexp.Compile(pattern)
  43. return string(r.ReplaceAll([]byte(str), []byte("")))
  44. }
  45. // Trim trim characters from both sides of the input.
  46. // If second argument is empty, it's will be remove spaces.
  47. func Trim(str, chars string) string {
  48. return LeftTrim(RightTrim(str, chars), chars)
  49. }
  50. // WhiteList remove characters that do not appear in the whitelist.
  51. func WhiteList(str, chars string) string {
  52. pattern := "[^" + chars + "]+"
  53. r, _ := regexp.Compile(pattern)
  54. return string(r.ReplaceAll([]byte(str), []byte("")))
  55. }
  56. // BlackList remove characters that appear in the blacklist.
  57. func BlackList(str, chars string) string {
  58. pattern := "[" + chars + "]+"
  59. r, _ := regexp.Compile(pattern)
  60. return string(r.ReplaceAll([]byte(str), []byte("")))
  61. }
  62. // StripLow remove characters with a numerical value < 32 and 127, mostly control characters.
  63. // If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD).
  64. func StripLow(str string, keepNewLines bool) string {
  65. chars := ""
  66. if keepNewLines {
  67. chars = "\x00-\x09\x0B\x0C\x0E-\x1F\x7F"
  68. } else {
  69. chars = "\x00-\x1F\x7F"
  70. }
  71. return BlackList(str, chars)
  72. }
  73. // ReplacePattern replace regular expression pattern in string
  74. func ReplacePattern(str, pattern, replace string) string {
  75. r, _ := regexp.Compile(pattern)
  76. return string(r.ReplaceAll([]byte(str), []byte(replace)))
  77. }
  78. // Escape replace <, >, & and " with HTML entities.
  79. var Escape = html.EscapeString
  80. func addSegment(inrune, segment []rune) []rune {
  81. if len(segment) == 0 {
  82. return inrune
  83. }
  84. if len(inrune) != 0 {
  85. inrune = append(inrune, '_')
  86. }
  87. inrune = append(inrune, segment...)
  88. return inrune
  89. }
  90. // UnderscoreToCamelCase converts from underscore separated form to camel case form.
  91. // Ex.: my_func => MyFunc
  92. func UnderscoreToCamelCase(s string) string {
  93. return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1)
  94. }
  95. // CamelCaseToUnderscore converts from camel case form to underscore separated form.
  96. // Ex.: MyFunc => my_func
  97. func CamelCaseToUnderscore(str string) string {
  98. var output []rune
  99. var segment []rune
  100. for _, r := range str {
  101. if !unicode.IsLower(r) {
  102. output = addSegment(output, segment)
  103. segment = nil
  104. }
  105. segment = append(segment, unicode.ToLower(r))
  106. }
  107. output = addSegment(output, segment)
  108. return string(output)
  109. }
  110. // Reverse return reversed string
  111. func Reverse(s string) string {
  112. r := []rune(s)
  113. for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
  114. r[i], r[j] = r[j], r[i]
  115. }
  116. return string(r)
  117. }
  118. // GetLines split string by "\n" and return array of lines
  119. func GetLines(s string) []string {
  120. return strings.Split(s, "\n")
  121. }
  122. // GetLine return specified line of multiline string
  123. func GetLine(s string, index int) (string, error) {
  124. lines := GetLines(s)
  125. if index < 0 || index >= len(lines) {
  126. return "", errors.New("line index out of bounds")
  127. }
  128. return lines[index], nil
  129. }
  130. // RemoveTags remove all tags from HTML string
  131. func RemoveTags(s string) string {
  132. return ReplacePattern(s, "<[^>]*>", "")
  133. }
  134. // SafeFileName return safe string that can be used in file names
  135. func SafeFileName(str string) string {
  136. name := strings.ToLower(str)
  137. name = path.Clean(path.Base(name))
  138. name = strings.Trim(name, " ")
  139. separators, err := regexp.Compile(`[ &_=+:]`)
  140. if err == nil {
  141. name = separators.ReplaceAllString(name, "-")
  142. }
  143. legal, err := regexp.Compile(`[^[:alnum:]-.]`)
  144. if err == nil {
  145. name = legal.ReplaceAllString(name, "")
  146. }
  147. for strings.Contains(name, "--") {
  148. name = strings.Replace(name, "--", "-", -1)
  149. }
  150. return name
  151. }
  152. // NormalizeEmail canonicalize an email address.
  153. // The local part of the email address is lowercased for all domains; the hostname is always lowercased and
  154. // the local part of the email address is always lowercased for hosts that are known to be case-insensitive (currently only GMail).
  155. // Normalization follows special rules for known providers: currently, GMail addresses have dots removed in the local part and
  156. // are stripped of tags (e.g. some.one+tag@gmail.com becomes someone@gmail.com) and all @googlemail.com addresses are
  157. // normalized to @gmail.com.
  158. func NormalizeEmail(str string) (string, error) {
  159. if !IsEmail(str) {
  160. return "", fmt.Errorf("%s is not an email", str)
  161. }
  162. parts := strings.Split(str, "@")
  163. parts[0] = strings.ToLower(parts[0])
  164. parts[1] = strings.ToLower(parts[1])
  165. if parts[1] == "gmail.com" || parts[1] == "googlemail.com" {
  166. parts[1] = "gmail.com"
  167. parts[0] = strings.Split(ReplacePattern(parts[0], `\.`, ""), "+")[0]
  168. }
  169. return strings.Join(parts, "@"), nil
  170. }
  171. // Truncate a string to the closest length without breaking words.
  172. func Truncate(str string, length int, ending string) string {
  173. var aftstr, befstr string
  174. if len(str) > length {
  175. words := strings.Fields(str)
  176. before, present := 0, 0
  177. for i := range words {
  178. befstr = aftstr
  179. before = present
  180. aftstr = aftstr + words[i] + " "
  181. present = len(aftstr)
  182. if present > length && i != 0 {
  183. if (length - before) < (present - length) {
  184. return Trim(befstr, " /\\.,\"'#!?&@+-") + ending
  185. }
  186. return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending
  187. }
  188. }
  189. }
  190. return str
  191. }