Skip to content

Commit

Permalink
Do not treat numbers as word boundaries (#1)
Browse files Browse the repository at this point in the history
* Fix camelCase conversion for acronyms containing numbers

* Support acronyms that start with numbers

* update module

* Change default behavior

* Remove unnecessary tests

* Do not treat numbers as word boundaries

* Number followed by capital letter is delimiting
  • Loading branch information
emla9 authored May 6, 2024
1 parent 531aaa4 commit 8df16b4
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 76 deletions.
60 changes: 2 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,3 @@
# strcase
[![Godoc Reference](https://godoc.org/github.com/iancoleman/strcase?status.svg)](http://godoc.org/github.com/iancoleman/strcase)
[![Build Status](https://travis-ci.com/iancoleman/strcase.svg)](https://travis-ci.com/iancoleman/strcase)
[![Coverage](http://gocover.io/_badge/github.com/iancoleman/strcase?0)](http://gocover.io/github.com/iancoleman/strcase)
[![Go Report Card](https://goreportcard.com/badge/github.com/iancoleman/strcase)](https://goreportcard.com/report/github.com/iancoleman/strcase)
# go-strcase

strcase is a go package for converting string case to various cases (e.g. [snake case](https://en.wikipedia.org/wiki/Snake_case) or [camel case](https://en.wikipedia.org/wiki/CamelCase)) to see the full conversion table below.

## Example

```go
s := "AnyKind of_string"
```

| Function | Result |
|-------------------------------------------|----------------------|
| `ToSnake(s)` | `any_kind_of_string` |
| `ToSnakeWithIgnore(s, '.')` | `any_kind.of_string` |
| `ToScreamingSnake(s)` | `ANY_KIND_OF_STRING` |
| `ToKebab(s)` | `any-kind-of-string` |
| `ToScreamingKebab(s)` | `ANY-KIND-OF-STRING` |
| `ToDelimited(s, '.')` | `any.kind.of.string` |
| `ToScreamingDelimited(s, '.', '', true)` | `ANY.KIND.OF.STRING` |
| `ToScreamingDelimited(s, '.', ' ', true)` | `ANY.KIND OF.STRING` |
| `ToCamel(s)` | `AnyKindOfString` |
| `ToLowerCamel(s)` | `anyKindOfString` |


## Install

```bash
go get -u github.com/iancoleman/strcase
```

## Custom Acronyms for ToCamel && ToLowerCamel

Often times text can contain specific acronyms which you need to be handled a certain way.
Out of the box `strcase` treats the string "ID" as "Id" or "id" but there is no way to cater
for every case in the wild.

To configure your custom acronym globally you can use the following before running any conversion

```go
import (
"github.com/iancoleman/strcase"
)

func init() {
// results in "Api" using ToCamel("API")
// results in "api" using ToLowerCamel("API")
strcase.ConfigureAcronym("API", "api")

// results in "PostgreSQL" using ToCamel("PostgreSQL")
// results in "postgreSQL" using ToLowerCamel("PostgreSQL")
strcase.ConfigureAcronym("PostgreSQL", "PostgreSQL")

}

```
Forked from https://github.com/iancoleman/strcase
5 changes: 1 addition & 4 deletions camel.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,9 @@ func toCamelInitCase(s string, initCase bool) string {
}
prevIsCap = vIsCap

if vIsCap || vIsLow {
if vIsCap || vIsLow || v >= '0' && v <= '9' {
n.WriteByte(v)
capNext = false
} else if vIsNum := v >= '0' && v <= '9'; vIsNum {
n.WriteByte(v)
capNext = true
} else {
capNext = v == '_' || v == ' ' || v == '-' || v == '.'
}
Expand Down
6 changes: 5 additions & 1 deletion camel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ func toCamel(tb testing.TB) {
{"many_many_words", "ManyManyWords"},
{"AnyKind of_string", "AnyKindOfString"},
{"odd-fix", "OddFix"},
{"numbers2And55with000", "Numbers2And55With000"},
{"numbers2And55with000", "Numbers2And55with000"},
{"ID", "Id"},
{"CONSTANT_CASE", "ConstantCase"},
{"90s-kids", "90sKids"},
{"k8s_version", "K8sVersion"},
}
for _, i := range cases {
in := i[0]
Expand Down Expand Up @@ -72,6 +74,8 @@ func toLowerCamel(tb testing.TB) {
{"some string", "someString"},
{" some string", "someString"},
{"CONSTANT_CASE", "constantCase"},
{"90s-kids", "90sKids"},
{"k8s_version", "k8sVersion"},
}
for _, i := range cases {
in := i[0]
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/iancoleman/strcase
module github.com/zillow/go-strcase

go 1.16
5 changes: 2 additions & 3 deletions snake.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,8 @@ func ToScreamingDelimited(s string, delimiter uint8, ignore string, screaming bo
vIsNum := v >= '0' && v <= '9'
nextIsCap := next >= 'A' && next <= 'Z'
nextIsLow := next >= 'a' && next <= 'z'
nextIsNum := next >= '0' && next <= '9'
// add underscore if next letter case type is changed
if (vIsCap && (nextIsLow || nextIsNum)) || (vIsLow && (nextIsCap || nextIsNum)) || (vIsNum && (nextIsCap || nextIsLow)) {
if (vIsCap && nextIsLow || vIsLow && nextIsCap || vIsNum && nextIsCap) {
prevIgnore := ignore != "" && i > 0 && strings.ContainsAny(string(s[i-1]), ignore)
if !prevIgnore {
if vIsCap && nextIsLow {
Expand All @@ -95,7 +94,7 @@ func ToScreamingDelimited(s string, delimiter uint8, ignore string, screaming bo
}
}
n.WriteByte(v)
if vIsLow || vIsNum || nextIsNum {
if vIsLow || vIsNum && nextIsCap {
n.WriteByte(delimiter)
}
continue
Expand Down
20 changes: 11 additions & 9 deletions snake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,20 @@ func toSnake(tb testing.TB) {
{"ManyManyWords", "many_many_words"},
{"manyManyWords", "many_many_words"},
{"AnyKind of_string", "any_kind_of_string"},
{"numbers2and55with000", "numbers_2_and_55_with_000"},
{"numbers2and55with000", "numbers2and55with000"},
{"JSONData", "json_data"},
{"userID", "user_id"},
{"AAAbbb", "aa_abbb"},
{"1A2", "1_a_2"},
{"A1B", "a_1_b"},
{"A1A2A3", "a_1_a_2_a_3"},
{"A1 A2 A3", "a_1_a_2_a_3"},
{"AB1AB2AB3", "ab_1_ab_2_ab_3"},
{"AB1 AB2 AB3", "ab_1_ab_2_ab_3"},
{"1A2", "1_a2"},
{"A1B", "a1_b"},
{"A1A2A3", "a1_a2_a3"},
{"A1 A2 A3", "a1_a2_a3"},
{"AB1AB2AB3", "ab1_ab2_ab3"},
{"AB1 AB2 AB3", "ab1_ab2_ab3"},
{"some string", "some_string"},
{" some string", "some_string"},
{"K8sVersion", "k8s_version"},
{"90sKids", "90s_kids"},
}
for _, i := range cases {
in := i[0]
Expand Down Expand Up @@ -88,7 +90,7 @@ func toSnakeWithIgnore(tb testing.TB) {
{"ManyManyWords", "many_many_words"},
{"manyManyWords", "many_many_words"},
{"AnyKind of_string", "any_kind_of_string"},
{"numbers2and55with000", "numbers_2_and_55_with_000"},
{"numbers2and55with000", "numbers2and55with000"},
{"JSONData", "json_data"},
{"AwesomeActivity.UserID", "awesome_activity.user_id", "."},
{"AwesomeActivity.User.Id", "awesome_activity.user.id", "."},
Expand Down Expand Up @@ -135,7 +137,7 @@ func toDelimited(tb testing.TB) {
{"ManyManyWords", "many@many@words"},
{"manyManyWords", "many@many@words"},
{"AnyKind of_string", "any@kind@of@string"},
{"numbers2and55with000", "numbers@2@and@55@with@000"},
{"numbers2and55with000", "numbers2and55with000"},
{"JSONData", "json@data"},
{"userID", "user@id"},
{"AAAbbb", "aa@abbb"},
Expand Down

0 comments on commit 8df16b4

Please sign in to comment.