112 lines
2.4 KiB
Go

package stringutils
import (
"encoding/json"
"fmt"
"strings"
"unicode"
"unicode/utf8"
"github.com/xrash/smetrics"
)
var whitespace = rune(' ')
// RemoveSpecialCharacters ...
func RemoveSpecialCharacters(s string) string {
return strings.Map(
func(r rune) rune {
if r == '-' {
return -1
}
if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
return whitespace
}
return r
},
s,
)
}
// AdvancedStringSimilarity is like StringSimilarity but boosts the value if a appears directly in b.
func AdvancedStringSimilarity(a string, b string) float64 {
if a == b {
return 10000000
}
normalizedA := strings.Map(keepLettersAndDigits, a)
normalizedB := strings.Map(keepLettersAndDigits, b)
if normalizedA == normalizedB {
return 100000
}
s := StringSimilarity(a, b)
if strings.Contains(normalizedB, normalizedA) {
s += 0.6
if strings.HasPrefix(b, a) {
s += 0.4
}
}
return s
}
// StringSimilarity returns 1.0 if the strings are equal and goes closer to 0 when they are different.
func StringSimilarity(a string, b string) float64 {
return smetrics.JaroWinkler(a, b, 0.7, 4)
}
// Capitalize returns the string with the first letter capitalized.
func Capitalize(s string) string {
if s == "" {
return ""
}
r, n := utf8.DecodeRuneInString(s)
return string(unicode.ToUpper(r)) + s[n:]
}
// Plural returns the number concatenated to the proper pluralization of the word.
func Plural(count int, singular string) string {
if count == 1 || count == -1 {
return fmt.Sprintf("%d %s", count, singular)
}
switch singular {
case "activity":
singular = "activitie"
case "company":
singular = "companie"
}
return fmt.Sprintf("%d %ss", count, singular)
}
// ContainsUnicodeLetters tells you if unicode characters are inside the string.
func ContainsUnicodeLetters(s string) bool {
return len(s) != len([]rune(s))
}
// PrettyPrint prints the object as indented JSON data on the console.
func PrettyPrint(obj interface{}) {
// Currently, MarshalIndent doesn't support tabs.
// Change this back to using \t when it's implemented.
// See: https://github.com/json-iterator/go/pull/273
pretty, _ := json.MarshalIndent(obj, "", " ")
fmt.Println(string(pretty))
}
// keepLettersAndDigits removes everything but letters and digits when used in strings.Map.
func keepLettersAndDigits(r rune) rune {
if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
return -1
}
return r
}