-
Notifications
You must be signed in to change notification settings - Fork 158
/
Copy pathstrings.go
103 lines (89 loc) · 3.93 KB
/
strings.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// MIT License
// Copyright (c) 2020 Qi Yin <[email protected]>
package exstrings
import (
"unicode/utf8"
"github.com/thinkeridea/go-extend/exbytes"
"github.com/thinkeridea/go-extend/exunicode/exutf8"
)
// Reverse 反转字符串,通过 https://golang.org/doc/code.html#Library 收集
// 使用 utf8.DecodeRuneInString 改进性能,请见:https://github.com/thinkeridea/go-extend/issues/5
func Reverse(s string) string {
var start, size, end int
buf := make([]byte, len(s))
for end < len(s) {
_, size = utf8.DecodeRuneInString(s[start:])
end = start + size
copy(buf[len(buf)-end:], s[start:end])
start = end
}
return exbytes.ToString(buf)
}
// ReverseASCII 反转字符串, 只支持单字节编码,可以提供更快的反转
func ReverseASCII(s string) string {
b := []byte(s)
for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
b[i], b[j] = b[j], b[i]
}
return exbytes.ToString(b)
}
// UnsafeReverseASCII 反转字符串, 只支持单字节编码,不支持字面量字符串,
// 原地反转字符串,可以提供更快的性能,但需要注意安全。
func UnsafeReverseASCII(s string) string {
b := UnsafeToBytes(s)
for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
b[i], b[j] = b[j], b[i]
}
return exbytes.ToString(b)
}
// Replace 替换字符串
// 该方法是对标准库 strings.Replace 修改,配合 unsafe 包能有效减少内存分配。
func Replace(s, old, new string, n int) string {
return exbytes.ToString(UnsafeReplaceToBytes(s, old, new, n))
}
/*
Repeat 返回由字符串s的计数副本组成的新字符串。
该方法是对标准库 strings.Repeat 修改,对于创建大字符串能有效减少内存分配。
如果计数为负或 len(s) * count 溢出将触发panic。
*/
func Repeat(s string, count int) string {
return exbytes.ToString(RepeatToBytes(s, count))
}
// Join 使用 sep 连接 a 的字符串。
// 该方法是对标准库 strings.Join 修改,配合 unsafe 包能有效减少内存分配。
func Join(a []string, sep string) string {
switch len(a) {
case 0:
return ""
case 1:
return a[0]
case 2:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1]
case 3:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1] + sep + a[2]
}
return exbytes.ToString(JoinToBytes(a, sep))
}
// Copy 拷贝一个字符串,在截取字符串之后,我们得到一个大字符串的引用,这会导致内存泄漏。
// 如果我们引用一个较大字符串的子串,建议进行 copy 以便 GC 可以快速回收大字符串。
// 例如: exstrings.Copy(s[10:50]) 这会得到一个子串的拷贝,原字符串不使用可以被 GC 回收。
func Copy(src string) string {
buf := make([]byte, len(src))
copy(buf, src)
return exbytes.ToString(buf)
}
// SubString 是 exutf8.RuneSubString 的别名,提供字符数量截取字符串的方法,针对多字节字符安全高效的截取
// 如果 start 是非负数,返回的字符串将从 string 的 start 位置开始,从 0 开始计算。例如,在字符串 “abcdef” 中,在位置 0 的字符是 “a”,位置 2 的字符串是 “c” 等等。
// 如果 start 是负数,返回的字符串将从 string 结尾处向前数第 start 个字符开始。
// 如果 string 的长度小于 start,将返回空字符串。
//
// 如果提供了正数的 length,返回的字符串将从 start 处开始最多包括 length 个字符(取决于 string 的长度)。
// 如果提供了负数的 length,那么 string 末尾处的 length 个字符将会被省略(若 start 是负数则从字符串尾部算起)。如果 start 不在这段文本中,那么将返回空字符串。
// 如果提供了值为 0 的 length,返回的子字符串将从 start 位置开始直到字符串结尾。
func SubString(s string, start, length int) string {
return exutf8.RuneSubString(s, start, length)
}