Skip to content

Commit 266436b

Browse files
authored
feat: add string conversion functions (#466)
* feat: add string conversion functions * fix: fix `Capitalize`, update tests * fix: fix `Capitalize`, update tests * update README.md * update tests * update `Capitalize` * style: unify coding style
1 parent a66bf34 commit 266436b

File tree

5 files changed

+520
-0
lines changed

5 files changed

+520
-0
lines changed

README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,72 @@ sub := len("hellô")
12971297

12981298
[[play](https://go.dev/play/p/tuhgW_lWY8l)]
12991299

1300+
### PascalCase
1301+
1302+
Converts string to pascal case.
1303+
1304+
```go
1305+
str := lo.PascalCase("hello_world")
1306+
// HelloWorld
1307+
```
1308+
1309+
[[play](https://go.dev/play/p/iZkdeLP9oiB)]
1310+
1311+
### CamelCase
1312+
1313+
Converts string to camel case.
1314+
1315+
```go
1316+
str := lo.CamelCase("hello_world")
1317+
// helloWorld
1318+
```
1319+
1320+
[[play](https://go.dev/play/p/dtyFB58MBRp)]
1321+
1322+
### KebabCase
1323+
1324+
Converts string to kebab case.
1325+
1326+
```go
1327+
str := lo.KebabCase("helloWorld")
1328+
// hello-world
1329+
```
1330+
1331+
[[play](https://go.dev/play/p/2YTuPafwECA)]
1332+
1333+
### SnakeCase
1334+
1335+
Converts string to snake case.
1336+
1337+
```go
1338+
str := lo.SnakeCase("HelloWorld")
1339+
// hello_world
1340+
```
1341+
1342+
[[play](https://go.dev/play/p/QVKJG9nOnDg)]
1343+
1344+
### Words
1345+
1346+
Splits string into an array of its words.
1347+
1348+
```go
1349+
str := lo.Words("helloWorld")
1350+
// []string{"hello", "world"}
1351+
```
1352+
1353+
[[play](https://go.dev/play/p/2P4zhqqq61g)]
1354+
1355+
### Capitalize
1356+
1357+
Converts the first character of string to upper case and the remaining to lower case.
1358+
1359+
```go
1360+
str := lo.PascalCase("heLLO")
1361+
// Hello
1362+
```
1363+
1364+
[[play](https://go.dev/play/p/jBIJ_OFtFYp)]
1365+
13001366
### T2 -> T9
13011367

13021368
Creates a tuple from a list of values.

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111
github.com/thoas/go-funk v0.9.1
1212
go.uber.org/goleak v1.2.1
1313
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17
14+
golang.org/x/text v0.16.0
1415
)
1516

1617
require (

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
2222
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
2323
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
2424
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
25+
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
26+
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
2527
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
2628
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
2729
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

string.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package lo
22

33
import (
4+
"golang.org/x/text/cases"
5+
"golang.org/x/text/language"
46
"math/rand"
7+
"regexp"
58
"strings"
9+
"unicode"
610
"unicode/utf8"
711
)
812

@@ -14,6 +18,9 @@ var (
1418
AlphanumericCharset = append(LettersCharset, NumbersCharset...)
1519
SpecialCharset = []rune("!@#$%^&*()_+-=[]{}|;':\",./<>?")
1620
AllCharset = append(AlphanumericCharset, SpecialCharset...)
21+
22+
splitWordReg = regexp.MustCompile(`([a-z])([A-Z0-9])|([a-zA-Z])([0-9])|([0-9])([a-zA-Z])|([A-Z])([A-Z])([a-z])`)
23+
splitNumberLetterReg = regexp.MustCompile(`([0-9])([a-zA-Z])`)
1724
)
1825

1926
// RandomString return a random string.
@@ -94,3 +101,64 @@ func ChunkString[T ~string](str T, size int) []T {
94101
func RuneLength(str string) int {
95102
return utf8.RuneCountInString(str)
96103
}
104+
105+
// PascalCase converts string to pascal case.
106+
func PascalCase(str string) string {
107+
items := Words(str)
108+
for i, item := range items {
109+
items[i] = Capitalize(item)
110+
}
111+
return strings.Join(items, "")
112+
}
113+
114+
// CamelCase converts string to camel case.
115+
func CamelCase(str string) string {
116+
items := Words(str)
117+
for i, item := range items {
118+
item = strings.ToLower(item)
119+
if i > 0 {
120+
item = Capitalize(item)
121+
}
122+
items[i] = item
123+
}
124+
return strings.Join(items, "")
125+
}
126+
127+
// KebabCase converts string to kebab case.
128+
func KebabCase(str string) string {
129+
items := Words(str)
130+
for i, item := range items {
131+
items[i] = strings.ToLower(item)
132+
}
133+
return strings.Join(items, "-")
134+
}
135+
136+
// SnakeCase converts string to snake case.
137+
func SnakeCase(str string) string {
138+
items := Words(str)
139+
for i, item := range items {
140+
items[i] = strings.ToLower(item)
141+
}
142+
return strings.Join(items, "_")
143+
}
144+
145+
// Words splits string into an array of its words.
146+
func Words(str string) []string {
147+
str = splitWordReg.ReplaceAllString(str, `$1$3$5$7 $2$4$6$8$9`)
148+
// example: Int8Value => Int 8Value => Int 8 Value
149+
str = splitNumberLetterReg.ReplaceAllString(str, "$1 $2")
150+
var result strings.Builder
151+
for _, r := range str {
152+
if unicode.IsLetter(r) || unicode.IsDigit(r) {
153+
result.WriteRune(r)
154+
} else {
155+
result.WriteRune(' ')
156+
}
157+
}
158+
return strings.Fields(result.String())
159+
}
160+
161+
// Capitalize converts the first character of string to upper case and the remaining to lower case.
162+
func Capitalize(str string) string {
163+
return cases.Title(language.English).String(str)
164+
}

0 commit comments

Comments
 (0)