parent
2eec27c695
commit
cd3f52170f
@ -0,0 +1,14 @@
|
||||
package str
|
||||
|
||||
// IsString check if the value data type is string or not.
|
||||
func (sst *Str) IsString(v any) bool {
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
switch v.(type) {
|
||||
case string:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package str
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStr_IsString(t *testing.T) {
|
||||
fmt.Println(StrTool.IsString("hello world!"))
|
||||
fmt.Println(StrTool.IsString(123))
|
||||
fmt.Println(StrTool.IsString(true))
|
||||
fmt.Println(StrTool.IsString(nil))
|
||||
fmt.Println(StrTool.IsString([]string{"hello", "world"}))
|
||||
fmt.Println(StrTool.IsString(map[string]string{"hello": "world"}))
|
||||
fmt.Println(StrTool.IsString(struct{}{}))
|
||||
|
||||
}
|
||||
@ -0,0 +1,246 @@
|
||||
package str
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Capitalize converts the first character of a string to upper case and the remaining to lower case.
|
||||
func (sst *Str) Capitalize(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
out := make([]rune, len(s))
|
||||
for i, v := range s {
|
||||
if i == 0 {
|
||||
out[i] = unicode.ToUpper(v)
|
||||
} else {
|
||||
out[i] = unicode.ToLower(v)
|
||||
}
|
||||
}
|
||||
|
||||
return string(out)
|
||||
}
|
||||
|
||||
// CamelCase covert string to camelCase string.
|
||||
func (sst *Str) CamelCase(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
res := ""
|
||||
blankSpace := " "
|
||||
regex, _ := regexp.Compile("[-_&]+")
|
||||
ss := regex.ReplaceAllString(s, blankSpace)
|
||||
for i, v := range strings.Split(ss, blankSpace) {
|
||||
vv := []rune(v)
|
||||
if i == 0 {
|
||||
if vv[i] >= 65 && vv[i] <= 96 {
|
||||
vv[0] += 32
|
||||
}
|
||||
res += string(vv)
|
||||
} else {
|
||||
res += sst.Capitalize(v)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// UpperFirst converts the first character of string to upper case.
|
||||
func (sst *Str) UpperFirst(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
r = unicode.ToUpper(r)
|
||||
|
||||
return string(r) + s[size:]
|
||||
}
|
||||
|
||||
// LowerFirst converts the first character of string to lower case.
|
||||
func (sst *Str) LowerFirst(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
r = unicode.ToLower(r)
|
||||
|
||||
return string(r) + s[size:]
|
||||
}
|
||||
|
||||
// PadEnd pads string on the right side if it's shorter than size.
|
||||
// Padding characters are truncated if they exceed size.
|
||||
func (sst *Str) PadEnd(source string, size int, padStr string) string {
|
||||
len1 := len(source)
|
||||
len2 := len(padStr)
|
||||
|
||||
if len1 >= size {
|
||||
return source
|
||||
}
|
||||
|
||||
fill := ""
|
||||
if len2 >= size-len1 {
|
||||
fill = padStr[0 : size-len1]
|
||||
} else {
|
||||
fill = strings.Repeat(padStr, size-len1)
|
||||
}
|
||||
return source + fill[0:size-len1]
|
||||
}
|
||||
|
||||
// PadStart pads string on the left side if it's shorter than size.
|
||||
// Padding characters are truncated if they exceed size.
|
||||
func (sst *Str) PadStart(source string, size int, padStr string) string {
|
||||
len1 := len(source)
|
||||
len2 := len(padStr)
|
||||
|
||||
if len1 >= size {
|
||||
return source
|
||||
}
|
||||
|
||||
fill := ""
|
||||
if len2 >= size-len1 {
|
||||
fill = padStr[0 : size-len1]
|
||||
} else {
|
||||
fill = strings.Repeat(padStr, size-len1)
|
||||
}
|
||||
return fill[0:size-len1] + source
|
||||
}
|
||||
|
||||
// KebabCase covert string to kebab-case
|
||||
func (sst *Str) KebabCase(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(`[\W|_]+`)
|
||||
blankSpace := " "
|
||||
match := regex.ReplaceAllString(s, blankSpace)
|
||||
rs := strings.Split(match, blankSpace)
|
||||
|
||||
var res []string
|
||||
for _, v := range rs {
|
||||
splitWords := splitWordsToLower(v)
|
||||
if len(splitWords) > 0 {
|
||||
res = append(res, splitWords...)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(res, "-")
|
||||
}
|
||||
|
||||
// SnakeCase covert string to snake_case
|
||||
func (sst *Str) SnakeCase(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(`[\W|_]+`)
|
||||
blankSpace := " "
|
||||
match := regex.ReplaceAllString(s, blankSpace)
|
||||
rs := strings.Split(match, blankSpace)
|
||||
|
||||
var res []string
|
||||
for _, v := range rs {
|
||||
splitWords := splitWordsToLower(v)
|
||||
if len(splitWords) > 0 {
|
||||
res = append(res, splitWords...)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(res, "_")
|
||||
}
|
||||
|
||||
// ReverseStr return string whose char order is reversed to the given string
|
||||
func (sst *Str) ReverseStr(s string) string {
|
||||
r := []rune(s)
|
||||
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
|
||||
r[i], r[j] = r[j], r[i]
|
||||
}
|
||||
return string(r)
|
||||
}
|
||||
|
||||
// Wrap a string with another string.
|
||||
func (sst *Str) Wrap(str string, wrapWith string) string {
|
||||
if str == "" || wrapWith == "" {
|
||||
return str
|
||||
}
|
||||
var sb strings.Builder
|
||||
sb.WriteString(wrapWith)
|
||||
sb.WriteString(str)
|
||||
sb.WriteString(wrapWith)
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// Unwrap a given string from anther string. will change str value
|
||||
func (sst *Str) Unwrap(str string, wrapToken string) string {
|
||||
if str == "" || wrapToken == "" {
|
||||
return str
|
||||
}
|
||||
|
||||
firstIndex := strings.Index(str, wrapToken)
|
||||
lastIndex := strings.LastIndex(str, wrapToken)
|
||||
|
||||
if firstIndex == 0 && lastIndex > 0 && lastIndex <= len(str)-1 {
|
||||
if len(wrapToken) <= lastIndex {
|
||||
str = str[len(wrapToken):lastIndex]
|
||||
}
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// SplitEx split a given string whether the result contains empty string
|
||||
func (sst *Str) SplitEx(s, sep string, removeEmptyString bool) []string {
|
||||
if sep == "" {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
n := strings.Count(s, sep) + 1
|
||||
a := make([]string, n)
|
||||
n--
|
||||
i := 0
|
||||
sepSave := 0
|
||||
ignore := false
|
||||
|
||||
for i < n {
|
||||
m := strings.Index(s, sep)
|
||||
if m < 0 {
|
||||
break
|
||||
}
|
||||
ignore = false
|
||||
if removeEmptyString {
|
||||
if s[:m+sepSave] == "" {
|
||||
ignore = true
|
||||
}
|
||||
}
|
||||
if !ignore {
|
||||
a[i] = s[:m+sepSave]
|
||||
s = s[m+len(sep):]
|
||||
i++
|
||||
} else {
|
||||
s = s[m+len(sep):]
|
||||
}
|
||||
}
|
||||
|
||||
var ret []string
|
||||
if removeEmptyString {
|
||||
if s != "" {
|
||||
a[i] = s
|
||||
ret = a[:i+1]
|
||||
} else {
|
||||
ret = a[:i]
|
||||
}
|
||||
} else {
|
||||
a[i] = s
|
||||
ret = a[:i+1]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
package str
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStr_Capitalize(t *testing.T) {
|
||||
fmt.Println(StrTool.Capitalize("hello world!"))
|
||||
//Hello world!
|
||||
fmt.Println(StrTool.CamelCase("hello world!"))
|
||||
//helloWorld!
|
||||
fmt.Println(StrTool.CamelCase("test_ok"))
|
||||
//testOk
|
||||
}
|
||||
|
||||
func TestStr_UpperFirst(t *testing.T) {
|
||||
fmt.Println(StrTool.UpperFirst("hello world!"))
|
||||
//Hello world!
|
||||
fmt.Println(StrTool.UpperFirst("test_ok"))
|
||||
//Test ok
|
||||
fmt.Println(StrTool.LowerFirst("Hello world!"))
|
||||
//hello world!
|
||||
}
|
||||
|
||||
func TestStr_PadEnd(t *testing.T) {
|
||||
fmt.Println(StrTool.PadEnd("hello world!", 100, "*"))
|
||||
fmt.Println(StrTool.PadEnd("hello world!", 100, "-"))
|
||||
fmt.Println(StrTool.PadEnd("hello world!", 100, " "))
|
||||
//hello world!****************************************************************************************
|
||||
//hello world!----------------------------------------------------------------------------------------
|
||||
//hello world!
|
||||
}
|
||||
func TestStr_PadStart(t *testing.T) {
|
||||
fmt.Println(StrTool.PadStart("hello world!", 100, "*"))
|
||||
fmt.Println(StrTool.PadStart("hello world!", 100, "-"))
|
||||
fmt.Println(StrTool.PadStart("hello world!", 100, " "))
|
||||
|
||||
//****************************************************************************************hello world!
|
||||
//----------------------------------------------------------------------------------------hello world!
|
||||
// hello world!
|
||||
}
|
||||
|
||||
func TestStr_KebabCase(t *testing.T) {
|
||||
fmt.Println(StrTool.KebabCase("hello world!"))
|
||||
//hello-world
|
||||
fmt.Println(StrTool.KebabCase("test_ok"))
|
||||
//test-ok
|
||||
}
|
||||
func TestStr_SnakeCase(t *testing.T) {
|
||||
fmt.Println(StrTool.SnakeCase("hello world!"))
|
||||
//hello_world
|
||||
fmt.Println(StrTool.SnakeCase("test_ok"))
|
||||
//test_ok
|
||||
}
|
||||
|
||||
func TestStr_Wrap(t *testing.T) {
|
||||
fmt.Println(StrTool.Wrap("hello world!", "100"))
|
||||
//100hello world!100
|
||||
|
||||
}
|
||||
func TestStr_Unwrap(t *testing.T) {
|
||||
fmt.Println(StrTool.Unwrap("100hello world!100", "100"))
|
||||
//hello world!
|
||||
}
|
||||
func TestStr_ReverseStr(t *testing.T) {
|
||||
fmt.Println(StrTool.ReverseStr("hello world!"))
|
||||
//!dlrow olleh
|
||||
}
|
||||
|
||||
func TestStr_SplitEx(t *testing.T) {
|
||||
fmt.Println(StrTool.SplitEx("hello world!", "world", true))
|
||||
fmt.Println(StrTool.SplitEx("hello world!", "world", false))
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package str
|
||||
|
||||
import "strings"
|
||||
|
||||
// splitWordsToLower split a string into worlds by uppercase char
|
||||
func splitWordsToLower(s string) []string {
|
||||
var res []string
|
||||
|
||||
upperIndexes := upperIndex(s)
|
||||
l := len(upperIndexes)
|
||||
if upperIndexes == nil || l == 0 {
|
||||
if s != "" {
|
||||
res = append(res, s)
|
||||
}
|
||||
return res
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
if i < l-1 {
|
||||
res = append(res, strings.ToLower(s[upperIndexes[i]:upperIndexes[i+1]]))
|
||||
} else {
|
||||
res = append(res, strings.ToLower(s[upperIndexes[i]:]))
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// upperIndex get a int slice which elements are all the uppercase char index of a string
|
||||
func upperIndex(s string) []int {
|
||||
var res []int
|
||||
for i := 0; i < len(s); i++ {
|
||||
if 64 < s[i] && s[i] < 91 {
|
||||
res = append(res, i)
|
||||
}
|
||||
}
|
||||
if len(s) > 0 && res != nil && res[0] != 0 {
|
||||
res = append([]int{0}, res...)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package str
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInternal(tt *testing.T) {
|
||||
fmt.Println(splitWordsToLower("Hello World,goodbye world!"))
|
||||
fmt.Println(upperIndex("Hello World,goodbye world!"))
|
||||
}
|
||||
Loading…
Reference in new issue