From 5cfb11f036b2c7ee6bc3fc0275ef9b5ca0f136be Mon Sep 17 00:00:00 2001 From: dudaodong Date: Wed, 14 Dec 2022 21:17:30 +0800 Subject: [PATCH] feat: fix and add SnakeCase/UpperSnakeCase --- strutil/string.go | 31 ++++++++++++++---------------- strutil/string_internal.go | 39 -------------------------------------- strutil/string_test.go | 32 ++++++++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 59 deletions(-) diff --git a/strutil/string.go b/strutil/string.go index ce22a3c..55bab74 100644 --- a/strutil/string.go +++ b/strutil/string.go @@ -4,7 +4,6 @@ package strutil import ( - "regexp" "strings" "unicode" "unicode/utf8" @@ -160,33 +159,31 @@ func PadStart(source string, size int, padStr string) string { // non letters and numbers will be ignored // eg. "Foo-#1😄$_%^&*(1bar" => "foo-1-1-bar" func KebabCase(s string) string { - strs := splitIntoStrings(s, false) - return strings.Join(strs, "-") + result := splitIntoStrings(s, false) + return strings.Join(result, "-") } // UpperKebabCase covert string to upper KEBAB-CASE // non letters and numbers will be ignored // eg. "Foo-#1😄$_%^&*(1bar" => "FOO-1-1-BAR" func UpperKebabCase(s string) string { - strs := splitIntoStrings(s, true) - return strings.Join(strs, "-") + result := splitIntoStrings(s, true) + return strings.Join(result, "-") } // SnakeCase covert string to snake_case +// non letters and numbers will be ignored +// eg. "Foo-#1😄$_%^&*(1bar" => "foo_1_1_bar" func SnakeCase(s string) string { - re := regexp.MustCompile(`[\W|_]+`) - space := " " - match := re.ReplaceAllString(s, space) - rs := strings.Split(match, space) - - var result []string - for _, v := range rs { - splitWords := splitWordsToLower(v) - if len(splitWords) > 0 { - result = append(result, splitWords...) - } - } + result := splitIntoStrings(s, false) + return strings.Join(result, "_") +} +// UpperSnakeCase covert string to upper SNAKE_CASE +// non letters and numbers will be ignored +// eg. "Foo-#1😄$_%^&*(1bar" => "FOO_1_1_BAR" +func UpperSnakeCase(s string) string { + result := splitIntoStrings(s, true) return strings.Join(result, "_") } diff --git a/strutil/string_internal.go b/strutil/string_internal.go index d140682..2d4b54c 100644 --- a/strutil/string_internal.go +++ b/strutil/string_internal.go @@ -1,47 +1,9 @@ package strutil import ( - "strings" "unicode" ) -// splitWordsToLower split a string into worlds by uppercase char -func splitWordsToLower(s string) []string { - var result []string - - upperIndexes := upperIndex(s) - l := len(upperIndexes) - if upperIndexes == nil || l == 0 { - if s != "" { - result = append(result, s) - } - return result - } - for i := 0; i < l; i++ { - if i < l-1 { - result = append(result, strings.ToLower(s[upperIndexes[i]:upperIndexes[i+1]])) - } else { - result = append(result, strings.ToLower(s[upperIndexes[i]:])) - } - } - return result -} - -// upperIndex get a int slice which elements are all the uppercase char index of a string -func upperIndex(s string) []int { - var result []int - for i := 0; i < len(s); i++ { - if 64 < s[i] && s[i] < 91 { - result = append(result, i) - } - } - if len(s) > 0 && result != nil && result[0] != 0 { - result = append([]int{0}, result...) - } - - return result -} - func splitIntoStrings(s string, upperCase bool) []string { var runes [][]rune lastCharType := 0 @@ -83,7 +45,6 @@ func splitIntoStrings(s string, upperCase bool) []string { result = append(result, string(toUpperAll(rs))) } else { result = append(result, string(toLowerAll(rs))) - } } } diff --git a/strutil/string_test.go b/strutil/string_test.go index 21c5422..85ffc25 100644 --- a/strutil/string_test.go +++ b/strutil/string_test.go @@ -94,20 +94,46 @@ func TestSnakeCase(t *testing.T) { assert := internal.NewAssert(t, "TestSnakeCase") cases := map[string]string{ + "": "", + "foo-bar": "foo_bar", + "--Foo---Bar-": "foo_bar", "Foo Bar-": "foo_bar", "foo_Bar": "foo_bar", "fooBar": "foo_bar", - "__FOO_BAR__": "f_o_o_b_a_r", + "FOOBAR": "foobar", + "FOO_BAR": "foo_bar", + "__FOO_BAR__": "foo_bar", "$foo@Bar": "foo_bar", " $#$Foo 22 bar ": "foo_22_bar", - "aBbc-s$@a&%_B.B^C": "a_bbc_s_a_b_b_c", + "Foo-#1😄$_%^&*(1bar": "foo_1_1_bar", } for k, v := range cases { assert.Equal(v, SnakeCase(k)) } +} - assert.Equal("", SnakeCase("")) +func TestUpperSnakeCase(t *testing.T) { + assert := internal.NewAssert(t, "TestUpperSnakeCase") + + cases := map[string]string{ + "": "", + "foo-bar": "FOO_BAR", + "--Foo---Bar-": "FOO_BAR", + "Foo Bar-": "FOO_BAR", + "foo_Bar": "FOO_BAR", + "fooBar": "FOO_BAR", + "FOOBAR": "FOOBAR", + "FOO_BAR": "FOO_BAR", + "__FOO_BAR__": "FOO_BAR", + "$foo@Bar": "FOO_BAR", + " $#$Foo 22 bar ": "FOO_22_BAR", + "Foo-#1😄$_%^&*(1bar": "FOO_1_1_BAR", + } + + for k, v := range cases { + assert.Equal(v, UpperSnakeCase(k)) + } } func TestUpperFirst(t *testing.T) {