podman

Форк
0
270 строк · 7.8 Кб
1
package govalidator
2

3
import (
4
	"errors"
5
	"fmt"
6
	"html"
7
	"math"
8
	"path"
9
	"regexp"
10
	"strings"
11
	"unicode"
12
	"unicode/utf8"
13
)
14

15
// Contains checks if the string contains the substring.
16
func Contains(str, substring string) bool {
17
	return strings.Contains(str, substring)
18
}
19

20
// Matches checks if string matches the pattern (pattern is regular expression)
21
// In case of error return false
22
func Matches(str, pattern string) bool {
23
	match, _ := regexp.MatchString(pattern, str)
24
	return match
25
}
26

27
// LeftTrim trims characters from the left side of the input.
28
// If second argument is empty, it will remove leading spaces.
29
func LeftTrim(str, chars string) string {
30
	if chars == "" {
31
		return strings.TrimLeftFunc(str, unicode.IsSpace)
32
	}
33
	r, _ := regexp.Compile("^[" + chars + "]+")
34
	return r.ReplaceAllString(str, "")
35
}
36

37
// RightTrim trims characters from the right side of the input.
38
// If second argument is empty, it will remove trailing spaces.
39
func RightTrim(str, chars string) string {
40
	if chars == "" {
41
		return strings.TrimRightFunc(str, unicode.IsSpace)
42
	}
43
	r, _ := regexp.Compile("[" + chars + "]+$")
44
	return r.ReplaceAllString(str, "")
45
}
46

47
// Trim trims characters from both sides of the input.
48
// If second argument is empty, it will remove spaces.
49
func Trim(str, chars string) string {
50
	return LeftTrim(RightTrim(str, chars), chars)
51
}
52

53
// WhiteList removes characters that do not appear in the whitelist.
54
func WhiteList(str, chars string) string {
55
	pattern := "[^" + chars + "]+"
56
	r, _ := regexp.Compile(pattern)
57
	return r.ReplaceAllString(str, "")
58
}
59

60
// BlackList removes characters that appear in the blacklist.
61
func BlackList(str, chars string) string {
62
	pattern := "[" + chars + "]+"
63
	r, _ := regexp.Compile(pattern)
64
	return r.ReplaceAllString(str, "")
65
}
66

67
// StripLow removes characters with a numerical value < 32 and 127, mostly control characters.
68
// If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD).
69
func StripLow(str string, keepNewLines bool) string {
70
	chars := ""
71
	if keepNewLines {
72
		chars = "\x00-\x09\x0B\x0C\x0E-\x1F\x7F"
73
	} else {
74
		chars = "\x00-\x1F\x7F"
75
	}
76
	return BlackList(str, chars)
77
}
78

79
// ReplacePattern replaces regular expression pattern in string
80
func ReplacePattern(str, pattern, replace string) string {
81
	r, _ := regexp.Compile(pattern)
82
	return r.ReplaceAllString(str, replace)
83
}
84

85
// Escape replaces <, >, & and " with HTML entities.
86
var Escape = html.EscapeString
87

88
func addSegment(inrune, segment []rune) []rune {
89
	if len(segment) == 0 {
90
		return inrune
91
	}
92
	if len(inrune) != 0 {
93
		inrune = append(inrune, '_')
94
	}
95
	inrune = append(inrune, segment...)
96
	return inrune
97
}
98

99
// UnderscoreToCamelCase converts from underscore separated form to camel case form.
100
// Ex.: my_func => MyFunc
101
func UnderscoreToCamelCase(s string) string {
102
	return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1)
103
}
104

105
// CamelCaseToUnderscore converts from camel case form to underscore separated form.
106
// Ex.: MyFunc => my_func
107
func CamelCaseToUnderscore(str string) string {
108
	var output []rune
109
	var segment []rune
110
	for _, r := range str {
111

112
		// not treat number as separate segment
113
		if !unicode.IsLower(r) && string(r) != "_" && !unicode.IsNumber(r) {
114
			output = addSegment(output, segment)
115
			segment = nil
116
		}
117
		segment = append(segment, unicode.ToLower(r))
118
	}
119
	output = addSegment(output, segment)
120
	return string(output)
121
}
122

123
// Reverse returns reversed string
124
func Reverse(s string) string {
125
	r := []rune(s)
126
	for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
127
		r[i], r[j] = r[j], r[i]
128
	}
129
	return string(r)
130
}
131

132
// GetLines splits string by "\n" and return array of lines
133
func GetLines(s string) []string {
134
	return strings.Split(s, "\n")
135
}
136

137
// GetLine returns specified line of multiline string
138
func GetLine(s string, index int) (string, error) {
139
	lines := GetLines(s)
140
	if index < 0 || index >= len(lines) {
141
		return "", errors.New("line index out of bounds")
142
	}
143
	return lines[index], nil
144
}
145

146
// RemoveTags removes all tags from HTML string
147
func RemoveTags(s string) string {
148
	return ReplacePattern(s, "<[^>]*>", "")
149
}
150

151
// SafeFileName returns safe string that can be used in file names
152
func SafeFileName(str string) string {
153
	name := strings.ToLower(str)
154
	name = path.Clean(path.Base(name))
155
	name = strings.Trim(name, " ")
156
	separators, err := regexp.Compile(`[ &_=+:]`)
157
	if err == nil {
158
		name = separators.ReplaceAllString(name, "-")
159
	}
160
	legal, err := regexp.Compile(`[^[:alnum:]-.]`)
161
	if err == nil {
162
		name = legal.ReplaceAllString(name, "")
163
	}
164
	for strings.Contains(name, "--") {
165
		name = strings.Replace(name, "--", "-", -1)
166
	}
167
	return name
168
}
169

170
// NormalizeEmail canonicalize an email address.
171
// The local part of the email address is lowercased for all domains; the hostname is always lowercased and
172
// the local part of the email address is always lowercased for hosts that are known to be case-insensitive (currently only GMail).
173
// Normalization follows special rules for known providers: currently, GMail addresses have dots removed in the local part and
174
// are stripped of tags (e.g. some.one+tag@gmail.com becomes someone@gmail.com) and all @googlemail.com addresses are
175
// normalized to @gmail.com.
176
func NormalizeEmail(str string) (string, error) {
177
	if !IsEmail(str) {
178
		return "", fmt.Errorf("%s is not an email", str)
179
	}
180
	parts := strings.Split(str, "@")
181
	parts[0] = strings.ToLower(parts[0])
182
	parts[1] = strings.ToLower(parts[1])
183
	if parts[1] == "gmail.com" || parts[1] == "googlemail.com" {
184
		parts[1] = "gmail.com"
185
		parts[0] = strings.Split(ReplacePattern(parts[0], `\.`, ""), "+")[0]
186
	}
187
	return strings.Join(parts, "@"), nil
188
}
189

190
// Truncate a string to the closest length without breaking words.
191
func Truncate(str string, length int, ending string) string {
192
	var aftstr, befstr string
193
	if len(str) > length {
194
		words := strings.Fields(str)
195
		before, present := 0, 0
196
		for i := range words {
197
			befstr = aftstr
198
			before = present
199
			aftstr = aftstr + words[i] + " "
200
			present = len(aftstr)
201
			if present > length && i != 0 {
202
				if (length - before) < (present - length) {
203
					return Trim(befstr, " /\\.,\"'#!?&@+-") + ending
204
				}
205
				return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending
206
			}
207
		}
208
	}
209

210
	return str
211
}
212

213
// PadLeft pads left side of a string if size of string is less then indicated pad length
214
func PadLeft(str string, padStr string, padLen int) string {
215
	return buildPadStr(str, padStr, padLen, true, false)
216
}
217

218
// PadRight pads right side of a string if size of string is less then indicated pad length
219
func PadRight(str string, padStr string, padLen int) string {
220
	return buildPadStr(str, padStr, padLen, false, true)
221
}
222

223
// PadBoth pads both sides of a string if size of string is less then indicated pad length
224
func PadBoth(str string, padStr string, padLen int) string {
225
	return buildPadStr(str, padStr, padLen, true, true)
226
}
227

228
// PadString either left, right or both sides.
229
// Note that padding string can be unicode and more then one character
230
func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string {
231

232
	// When padded length is less then the current string size
233
	if padLen < utf8.RuneCountInString(str) {
234
		return str
235
	}
236

237
	padLen -= utf8.RuneCountInString(str)
238

239
	targetLen := padLen
240

241
	targetLenLeft := targetLen
242
	targetLenRight := targetLen
243
	if padLeft && padRight {
244
		targetLenLeft = padLen / 2
245
		targetLenRight = padLen - targetLenLeft
246
	}
247

248
	strToRepeatLen := utf8.RuneCountInString(padStr)
249

250
	repeatTimes := int(math.Ceil(float64(targetLen) / float64(strToRepeatLen)))
251
	repeatedString := strings.Repeat(padStr, repeatTimes)
252

253
	leftSide := ""
254
	if padLeft {
255
		leftSide = repeatedString[0:targetLenLeft]
256
	}
257

258
	rightSide := ""
259
	if padRight {
260
		rightSide = repeatedString[0:targetLenRight]
261
	}
262

263
	return leftSide + str + rightSide
264
}
265

266
// TruncatingErrorf removes extra args from fmt.Errorf if not formatted in the str object
267
func TruncatingErrorf(str string, args ...interface{}) error {
268
	n := strings.Count(str, "%s")
269
	return fmt.Errorf(str, args[:n]...)
270
}
271

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.