fulfil unit test cases of gstr

This commit is contained in:
John 2019-02-01 14:38:45 +08:00
parent 92c0bf9cdc
commit f2e149d3b3
5 changed files with 240 additions and 50 deletions

View File

@ -20,6 +20,8 @@ import (
"unicode/utf8" "unicode/utf8"
) )
// Replace returns a copy of the string <origin> with string <search> replaced by <replace>.
//
// 字符串替换(大小写敏感) // 字符串替换(大小写敏感)
func Replace(origin, search, replace string, count...int) string { func Replace(origin, search, replace string, count...int) string {
n := -1 n := -1
@ -29,6 +31,8 @@ func Replace(origin, search, replace string, count...int) string {
return strings.Replace(origin, search, replace, n) return strings.Replace(origin, search, replace, n)
} }
// Replace string by map.
//
// 使用map进行字符串替换(大小写敏感) // 使用map进行字符串替换(大小写敏感)
func ReplaceByMap(origin string, replaces map[string]string) string { func ReplaceByMap(origin string, replaces map[string]string) string {
result := origin result := origin
@ -38,16 +42,21 @@ func ReplaceByMap(origin string, replaces map[string]string) string {
return result return result
} }
// ToLower returns a copy of the string s with all Unicode letters mapped to their lower case.
// 字符串转换为小写 // 字符串转换为小写
func ToLower(s string) string { func ToLower(s string) string {
return strings.ToLower(s) return strings.ToLower(s)
} }
// ToUpper returns a copy of the string s with all Unicode letters mapped to their upper case.
//
// 字符串转换为大写 // 字符串转换为大写
func ToUpper(s string) string { func ToUpper(s string) string {
return strings.ToUpper(s) return strings.ToUpper(s)
} }
// UcFirst returns a copy of the string s with the first letter mapped to its upper case.
//
// 字符串首字母转换为大写 // 字符串首字母转换为大写
func UcFirst(s string) string { func UcFirst(s string) string {
if len(s) == 0 { if len(s) == 0 {
@ -59,6 +68,8 @@ func UcFirst(s string) string {
return s return s
} }
// LcFirst returns a copy of the string s with the first letter mapped to its lower case.
//
// 字符串首字母转换为小写 // 字符串首字母转换为小写
func LcFirst(s string) string { func LcFirst(s string) string {
if len(s) == 0 { if len(s) == 0 {
@ -89,11 +100,15 @@ func SearchArray (a []string, s string) int {
return -1 return -1
} }
// InArray tests whether the given string s is in string array a.
//
// 判断字符串是否在数组中 // 判断字符串是否在数组中
func InArray (a []string, s string) bool { func InArray (a []string, s string) bool {
return SearchArray(a, s) != -1 return SearchArray(a, s) != -1
} }
// IsLetterLower tests whether the given byte b is in lower case.
//
// 判断给定字符是否小写 // 判断给定字符是否小写
func IsLetterLower(b byte) bool { func IsLetterLower(b byte) bool {
if b >= byte('a') && b <= byte('z') { if b >= byte('a') && b <= byte('z') {
@ -102,6 +117,8 @@ func IsLetterLower(b byte) bool {
return false return false
} }
// IsLetterUpper tests whether the given byte b is in upper case.
//
// 判断给定字符是否大写 // 判断给定字符是否大写
func IsLetterUpper(b byte) bool { func IsLetterUpper(b byte) bool {
if b >= byte('A') && b <= byte('Z') { if b >= byte('A') && b <= byte('Z') {
@ -110,7 +127,9 @@ func IsLetterUpper(b byte) bool {
return false return false
} }
// 判断锁给字符串是否为数字 // IsNumeric tests whether the given string s is numeric.
//
// 判断锁给字符串是否为数字.
func IsNumeric(s string) bool { func IsNumeric(s string) bool {
length := len(s) length := len(s)
if length == 0 { if length == 0 {
@ -124,6 +143,8 @@ func IsNumeric(s string) bool {
return true return true
} }
// Returns the portion of string specified by the start and length parameters.
//
// 字符串截取,支持中文 // 字符串截取,支持中文
func SubStr(str string, start int, length...int) (substr string) { func SubStr(str string, start int, length...int) (substr string) {
// 将字符串的转换成[]rune // 将字符串的转换成[]rune
@ -150,6 +171,10 @@ func SubStr(str string, start int, length...int) (substr string) {
return string(rs[start : end]) return string(rs[start : end])
} }
// Returns the portion of string specified by the <length> parameters,
// if the length of str is greater than <length>,
// then the <suffix> will be appended to the result.
//
// 字符串长度截取限制,超过长度限制被截取并在字符串末尾追加指定的内容,支持中文 // 字符串长度截取限制,超过长度限制被截取并在字符串末尾追加指定的内容,支持中文
func StrLimit(str string, length int, suffix...string) (string) { func StrLimit(str string, length int, suffix...string) (string) {
rs := []rune(str) rs := []rune(str)
@ -164,6 +189,8 @@ func StrLimit(str string, length int, suffix...string) (string) {
} }
// Reverse a string. // Reverse a string.
//
// 字符串反转.
func Reverse(str string) string { func Reverse(str string) string {
runes := []rune(str) runes := []rune(str)
for i, j := 0, len(runes) - 1; i < j; i, j = i + 1, j - 1 { for i, j := 0, len(runes) - 1; i < j; i, j = i + 1, j - 1 {
@ -249,13 +276,94 @@ func ChunkSplit(body string, chunkLen int, end string) string {
return string(ns) return string(ns)
} }
// Return information about words used in a string. // Compare returns an integer comparing two strings lexicographically.
func WordCount(str string) []string { // The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
//
// 比较两个字符串。
func Compare(a, b string) int {
return strings.Compare(a, b)
}
// Equal reports whether s and t, interpreted as UTF-8 strings,
// are equal under Unicode case-folding, case-insensitive.
//
// 比较两个字符串是否相等(不区分大小写)。
func Equal(a, b string) bool {
return strings.EqualFold(a, b)
}
// Return the words used in a string.
//
// 分割字符串中的单词。
func Fields(str string) []string {
return strings.Fields(str) return strings.Fields(str)
} }
// Contains reports whether substr is within str.
//
// 判断是否substr存在于str中。
func Contains(str, substr string) bool {
return strings.Contains(str, substr)
}
// Contains reports whether substr is within str, case-insensitive.
//
// 判断是否substr存在于str中(不区分大小写)。
func ContainsI(str, substr string) bool {
return PosI(str, substr) != -1
}
// ContainsAny reports whether any Unicode code points in chars are within s.
//
// 判断是否s中是否包含chars指定的任意字符。
func ContainsAny(s, chars string) bool {
return strings.ContainsAny(s, chars)
}
// Return information about words used in a string.
//
// 返回字符串中单词的使用情况。
func CountWords(str string) map[string]int {
m := make(map[string]int)
buffer := bytes.NewBuffer(nil)
for _, rune := range []rune(str) {
if unicode.IsSpace(rune) {
if buffer.Len() > 0 {
m[buffer.String()]++
buffer.Reset()
}
} else {
buffer.WriteRune(rune)
}
}
if buffer.Len() > 0 {
m[buffer.String()]++
}
return m
}
// Return information about words used in a string.
//
// 返回字符串中字符的使用情况。
func CountChars(str string, noSpace...bool) map[string]int {
m := make(map[string]int)
countSpace := true
if len(noSpace) > 0 && noSpace[0] {
countSpace = false
}
for _, rune := range []rune(str) {
if !countSpace && unicode.IsSpace(rune) {
continue
}
m[string(rune)]++
}
return m
}
// Wraps a string to a given number of characters. // Wraps a string to a given number of characters.
// TODO: Enable cut param, see http://php.net/manual/en/function.wordwrap.php. // TODO: Enable cut param, see http://php.net/manual/en/function.wordwrap.php.
//
// 使用字符串断点将字符串打断为指定数量的字串。
func WordWrap(str string, width int, br string) string { func WordWrap(str string, width int, br string) string {
if br == "" { if br == "" {
br = "\n" br = "\n"
@ -314,11 +422,15 @@ func WordWrap(str string, width int, br string) string {
} }
// Get string length of unicode. // Get string length of unicode.
//
// UTF-8字符串长度。
func RuneLen(str string) int { func RuneLen(str string) int {
return utf8.RuneCountInString(str) return utf8.RuneCountInString(str)
} }
// Repeat a string. // Repeat returns a new string consisting of multiplier copies of the string input.
//
// 按照指定大小创建重复的字符串。
func Repeat(input string, multiplier int) string { func Repeat(input string, multiplier int) string {
return strings.Repeat(input, multiplier) return strings.Repeat(input, multiplier)
} }
@ -350,43 +462,6 @@ func Shuffle(str string) string {
return string(s) return string(s)
} }
// Strip whitespace (or other characters) from the beginning and end of a string.
//
// 去除字符串首尾处的空白字符(或者其他字符)。
func Trim(str string, characterMask ...string) string {
if len(characterMask) > 0 {
return strings.Trim(str, characterMask[0])
} else {
return strings.TrimSpace(str)
}
}
// Strip whitespace (or other characters) from the beginning of a string.
//
// 去除字符串首的空白字符(或者其他字符)。
func TrimLeft(str string, characterMask ...string) string {
mask := ""
if len(characterMask) == 0 {
mask = string([]byte{'\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0})
} else {
mask = characterMask[0]
}
return strings.TrimLeft(str, mask)
}
// Strip whitespace (or other characters) from the end of a string.
//
// 去除字符串尾的空白字符(或者其他字符)。
func TrimRight(str string, characterMask ...string) string {
mask := ""
if len(characterMask) == 0 {
mask = string([]byte{'\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0})
} else {
mask = characterMask[0]
}
return strings.TrimRight(str, mask)
}
// Split a string by a string, to an array. // Split a string by a string, to an array.
// //
// 此函数返回由字符串组成的数组,每个元素都是 str 的一个子串,它们被字符串 delimiter 作为边界点分割出来。 // 此函数返回由字符串组成的数组,每个元素都是 str 的一个子串,它们被字符串 delimiter 作为边界点分割出来。
@ -440,6 +515,8 @@ func Ord(char string) int {
return int(char[0]) return int(char[0])
} }
// HideStr replaces part of the the string by percentage from the middle.
//
// 按照百分比从字符串中间向两边隐藏字符(主要用于姓名、手机号、邮箱地址、身份证号等的隐藏)支持utf-8中文支持email格式。 // 按照百分比从字符串中间向两边隐藏字符(主要用于姓名、手机号、邮箱地址、身份证号等的隐藏)支持utf-8中文支持email格式。
func HideStr(str string, percent int, hide string) string { func HideStr(str string, percent int, hide string) string {
array := strings.Split(str, "@") array := strings.Split(str, "@")

View File

@ -4,7 +4,7 @@ import "strings"
// Find the position of the first occurrence of a substring in a string. // Find the position of the first occurrence of a substring in a string.
// //
// 返回 needle 在 haystack 中首次出现的数字位置 // 返回 needle 在 haystack 中首次出现的数字位置,找不到返回-1
func Pos(haystack, needle string, startOffset...int) int { func Pos(haystack, needle string, startOffset...int) int {
length := len(haystack) length := len(haystack)
offset := 0 offset := 0
@ -27,7 +27,7 @@ func Pos(haystack, needle string, startOffset...int) int {
// Find the position of the first occurrence of a case-insensitive substring in a string. // Find the position of the first occurrence of a case-insensitive substring in a string.
// //
// 返回在字符串 haystack 中 needle 首次出现的数字位置(不区分大小写) // 返回在字符串 haystack 中 needle 首次出现的数字位置(不区分大小写),找不到返回-1
func PosI(haystack, needle string, startOffset...int) int { func PosI(haystack, needle string, startOffset...int) int {
length := len(haystack) length := len(haystack)
offset := 0 offset := 0
@ -51,7 +51,7 @@ func PosI(haystack, needle string, startOffset...int) int {
// Find the position of the last occurrence of a substring in a string. // Find the position of the last occurrence of a substring in a string.
// //
// 查找指定字符串在目标字符串中最后一次出现的位置 // 查找指定字符串在目标字符串中最后一次出现的位置,找不到返回-1
func PosR(haystack, needle string, startOffset...int) int { func PosR(haystack, needle string, startOffset...int) int {
offset := 0 offset := 0
if len(startOffset) > 0 { if len(startOffset) > 0 {
@ -76,7 +76,7 @@ func PosR(haystack, needle string, startOffset...int) int {
// Find the position of the last occurrence of a case-insensitive substring in a string. // Find the position of the last occurrence of a case-insensitive substring in a string.
// //
// 以不区分大小写的方式查找指定字符串在目标字符串中最后一次出现的位置 // 以不区分大小写的方式查找指定字符串在目标字符串中最后一次出现的位置,找不到返回-1
func PosRI(haystack, needle string, startOffset...int) int { func PosRI(haystack, needle string, startOffset...int) int {
offset := 0 offset := 0
if len(startOffset) > 0 { if len(startOffset) > 0 {

View File

@ -0,0 +1,71 @@
// Copyright 2019 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gstr
import "strings"
// Strip whitespace (or other characters) from the beginning and end of a string.
//
// 去除字符串首尾处的空白字符(或者其他字符)。
func Trim(str string, characterMask ...string) string {
if len(characterMask) > 0 {
return strings.Trim(str, characterMask[0])
} else {
return strings.TrimSpace(str)
}
}
// Strip whitespace (or other characters) from the beginning of a string.
//
// 去除字符串首的空白字符(或者其他字符)。
func TrimLeft(str string, characterMask ...string) string {
mask := ""
if len(characterMask) == 0 {
mask = string([]byte{'\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0})
} else {
mask = characterMask[0]
}
return strings.TrimLeft(str, mask)
}
// Strip all of the given cut string from the beginning of a string.
//
// 去除字符串首的给定字符串。
func TrimLeftStr(str string, cut string) string {
for str[0 : len(cut)] == cut {
str = str[len(cut) : ]
}
return str
}
// Strip whitespace (or other characters) from the end of a string.
//
// 去除字符串尾的空白字符(或者其他字符)。
func TrimRight(str string, characterMask ...string) string {
mask := ""
if len(characterMask) == 0 {
mask = string([]byte{'\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0})
} else {
mask = characterMask[0]
}
return strings.TrimRight(str, mask)
}
// Strip all of the given cut string from the end of a string.
//
// 去除字符串尾的给定字符串。
func TrimRightStr(str string, cut string) string {
for {
length := len(str)
if str[length - len(cut) : length] == cut {
str = str[ : length - len(cut)]
} else {
break
}
}
return str
}

View File

@ -149,10 +149,38 @@ func Test_ChunkSplit(t *testing.T) {
}) })
} }
func Test_WordCount(t *testing.T) { func Test_Fields(t *testing.T) {
gtest.Case(t, func() { gtest.Case(t, func() {
gtest.Assert(gstr.WordCount("我爱 GoFrame!"), []string{"我爱", "GoFrame!"}) gtest.Assert(gstr.Fields("我爱 Go Frame"), []string{
gtest.Assert(gstr.WordCount("I love GoFrame!"), []string{"I", "love", "GoFrame!"}) "我爱", "Go", "Frame",
})
})
}
func Test_CountWords(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gstr.CountWords("我爱 Go Go Go"), map[string]int{
"Go" : 3,
"我爱" : 1,
})
})
}
func Test_CountChars(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gstr.CountChars("我爱 Go Go Go"), map[string]int{
" " : 3,
"G" : 3,
"o" : 3,
"我" : 1,
"爱" : 1,
})
gtest.Assert(gstr.CountChars("我爱 Go Go Go", true), map[string]int{
"G" : 3,
"o" : 3,
"我" : 1,
"爱" : 1,
})
}) })
} }
@ -204,6 +232,12 @@ func Test_TrimRight(t *testing.T) {
}) })
} }
func Test_TrimRightStr(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gstr.TrimRightStr("gogo我爱gogo", "go"), "gogo我爱")
})
}
func Test_TrimLeft(t *testing.T) { func Test_TrimLeft(t *testing.T) {
gtest.Case(t, func() { gtest.Case(t, func() {
gtest.Assert(gstr.TrimLeft(" \r123456\n "), "123456\n ") gtest.Assert(gstr.TrimLeft(" \r123456\n "), "123456\n ")
@ -211,6 +245,12 @@ func Test_TrimLeft(t *testing.T) {
}) })
} }
func Test_TrimLeftStr(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gstr.TrimLeftStr("gogo我爱gogo", "go"), "我爱gogo")
})
}
func Test_Split(t *testing.T) { func Test_Split(t *testing.T) {
gtest.Case(t, func() { gtest.Case(t, func() {
gtest.Assert(gstr.Split("1.2", "."), []string{"1", "2"}) gtest.Assert(gstr.Split("1.2", "."), []string{"1", "2"})

View File

@ -2,8 +2,10 @@ package main
import ( import (
"fmt" "fmt"
"gitee.com/johng/gf/g/string/gstr"
) )
func main() { func main() {
fmt.Println(string([]byte{'\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0})) fmt.Println(gstr.TrimLeftStr("gogo我爱gogo", "go"))
} fmt.Println(gstr.TrimRightStr("gogo我爱gogo", "go"))
}