strings庫
func EqualFold
func EqualFold(s, t string) bool
判斷兩個utf-8編碼字符串(將unicode大寫、小寫、標題三種格式字符視為相同)是否相同。
func main() {fmt.Println(strings.EqualFold("hello", "hello")) //truefmt.Println(strings.EqualFold("hello", "HELLO")) //truefmt.Println(strings.EqualFold("hello", "Hello")) //true
}
func HasPrefix
func HasPrefix(s, prefix string) bool
判斷s是否有前綴字符串prefix。
func main() {fmt.Println(strings.HasPrefix("golang", "go")) // truefmt.Println(strings.HasPrefix("golang", "lang")) // false
}
func HasSuffix
func HasSuffix(s, suffix string) bool
判斷s是否有后綴字符串suffix。
func main() {fmt.Println(strings.HasSuffix("hello.txt", ".txt")) // truefmt.Println(strings.HasSuffix("hello.txt", ".jpg")) // false
}
func Contains
func Contains(s, substr string) bool
判斷字符串s是否包含子串subs
func main() {fmt.Println(strings.Contains("hello world", "world")) // truefmt.Println(strings.Contains("golang", "java")) // false
}
func ContainsRune
func ContainsRune(s string, r rune) bool
判斷字符串s是否包含utf-8碼值r。
func main() {fmt.Println(strings.ContainsRune("你好,世界", '界')) // truefmt.Println(strings.ContainsRune("hello", '你')) // falsefmt.Println(strings.ContainsRune("hello", 'h')) // true
}
//這個是適用于單個Unicode字符檢查,而不是子串
//如果輸入多個字符的話,報這個錯:Too many characters in the rune literal
func ContainsAny
func ContainsAny(s, chars string) bool
判斷字符串s是否包含字符串chars中的任一字符。
func main() {fmt.Println(strings.ContainsAny("hello", "aeiou")) // true (包含 'e'、'o')fmt.Println(strings.ContainsAny("golang", "xyz")) // false
}
func Count
func Count(s, sep string) int
返回字符串s中有幾個不重復的sep子串。
func main() {fmt.Println(strings.Count("banana", "a")) // 3fmt.Println(strings.Count("hello", "l")) // 2fmt.Println(strings.Count("golang", "go")) // 1fmt.Println(strings.Count("aaaa", "")) //猜一下這個
}
func Index
func Index(s, sep string) int
子串sep在字符串s中第一次出現的位置,不存在則返回-1。
func main() {s := "hello world"fmt.Println(strings.Index(s, "world")) // 6fmt.Println(strings.Index(s, "go")) // -1 (找不到返回 -1)
}
func IndexByte
func IndexByte(s string, c byte) int
字符c在s中第一次出現的位置,不存在則返回-1。
func main() {s := "hello"fmt.Println(strings.IndexByte(s, 'e')) // 1fmt.Println(strings.IndexByte(s, 'x')) // -1
}
IndexByte適合查找**ASCII** 字符,因為
byte是單字節,無法直接表示多字節的 UTF-8 字符(例如中文)。
如果你要查找英文或單字節字符,可以用這個函數,性能會比 IndexRune
略好。
func IndexRune
func IndexRune(s string, r rune) int
unicode碼值r在s中第一次出現的位置,不存在則返回-1。
func main() {s := "你好,世界"fmt.Println(strings.IndexRune(s, '世')) // 9fmt.Println(strings.IndexRune(s, '界')) // 12fmt.Println(strings.IndexRune(s, '你')) // 0fmt.Println(strings.IndexRune(s, 'x')) // -1
}
對于多字節字符(如中文),IndexRune
可以正確識別并定位索引。
注意索引依舊是以字節為單位計算的。例如 “你好”:
'你'
占用 3 個字節,索引從 0~2;'好'
索引從 3~5。
所以'好'
的開始索引是 3。
func IndexAny
func IndexAny(s, chars string) int
字符串chars中的任一utf-8碼值在s中第一次出現的位置,如果不存在或者chars為空字符串則返回-1。
func main() {s := "hello"fmt.Println(strings.IndexAny(s, "jker")) // 1 (因為 'e' 出現在索引 1)fmt.Println(strings.IndexAny(s, "xyz")) // -1 (找不到)//猜一下下面的fmt.Println(strings.IndexAny(s, "loo")) fmt.Println(strings.IndexAny(s, "ollo"))fmt.Println(strings.IndexAny(s, "olloe"))
}
一次性查找多個可能的字符,只要匹配到其中一個字符,就返回首次出現的索引。
func IndexFunc
func IndexFunc(s string, f func(rune) bool) int
在字符串 s
中,從左到右遍歷,每次取出一個 Unicode 字符 r
并調用 f(r)
判斷是否為 true,如果是,則返回該字符在字符串中的索引。若遍歷完都不為 true
,返回 -1。
func main() {s := "123abc"// 找到第一個字母的位置index := strings.IndexFunc(s, func(r rune) bool {return unicode.IsLetter(r)})fmt.Println(index) // 3 ("a" 的位置)
}
f
是一個判斷函數,通常會使用到 unicode
包的判斷方法(如 unicode.IsLetter
、unicode.IsDigit
、unicode.IsSpace
等)。
適合自定義復雜的匹配條件。
func LastIndex
func LastIndex(s, sep string) int
子串sep在字符串s中最后一次出現的位置,不存在則返回-1。
func main() {s := "hello world world"fmt.Println(strings.LastIndex(s, "world")) // 12fmt.Println(strings.LastIndex(s, "go")) // -1
}
LastIndex
用于反向搜索子串的出現位置。
例如文件路徑處理時,需要找最后一個斜杠 /
的位置,可以用 LastIndex
來提取文件名等。
func LastIndexAny
func LastIndexAny(s, chars string) int
在字符串 s
中查找 chars
中任意一個字符最后一次出現的位置,找不到返回 -1。
func main() {s := "hello world"fmt.Println(strings.LastIndexAny(s, "o")) //'0' 7//猜一下fmt.Println(strings.LastIndexAny(s, "hello"))
}
func LastIndexFunc
func LastIndexFunc(s string, f func(rune) bool) int
從右往左遍歷字符串 s
,每次取出一個 Unicode 字符 r
,調用 f(r)
判斷是否為 true
,
若是,則返回該字符在字符串中的索引,否則 -1
func main() {s := "GoLang 123"// 找到最后一個字母index := strings.LastIndexFunc(s, func(r rune) bool {return unicode.IsLetter(r)})fmt.Println(index) // 5 ('g' 的索引)
}
func Title
func Title(s string) string
返回字符串 s
的拷貝,其中每個“單詞”的首字母都被轉換為 Title Case(類似首字母大寫)。
- 注意:“單詞” 的定義基于 Unicode 標準,會按照空格或非字母邊界來拆分。
func main() {s := "her royal highness"fmt.Println(strings.Title(s)) // "Her Royal Highness"
}
func ToLower
func ToLower(s string) string
返回將所有字母都轉為對應的小寫版本的拷貝。
func main() {fmt.Println(strings.ToLower("Hello WORLD!")) // "hello world!"
}
func ToUpper
func ToUpper(s string) string
返回將所有字母都轉為對應的大寫版本的拷貝。
func main() {fmt.Println(strings.ToUpper("Hello WORLD!")) // "HELLO WORLD!"
}
func ToTitle
func ToTitle(s string) string
返回將所有字母都轉為對應的標題版本的拷貝。
func main() {fmt.Println(strings.ToTitle("loud noises")) //LOUD NOISESs := "? ? ? hello"fmt.Println(strings.ToUpper(s)) // "? ? ? HELLO"fmt.Println(strings.ToTitle(s)) // "? ? ? HELLO"
}
區別于 strings.ToUpper
:
ToTitle
對普通字母的效果等同于ToUpper
- 但對于某些特殊的 Unicode 字母(如
?
、?
),ToTitle
會轉換成Titlecase
而不是Uppercase
func Repeat
func Repeat(s string, count int) string
返回一個新字符串,由 s
重復 count
次拼接而成。
func main() {fmt.Println(strings.Repeat("ha", 3)) // "hahaha"
}
func Replace
func Replace(s, old, new string, n int) string
在字符串 s
中,把 old
替換成 new
,共替換 n
次,返回新字符串。若 n
< 0,則替換所有出現。
package mainimport ("fmt""strings"
)func main() {s := "hello world world"fmt.Println(strings.Replace(s, "world", "Go", 1)) // "hello Go world"fmt.Println(strings.Replace(s, "world", "Go", -1)) // "hello Go Go"//ReplaceAll(s, old, new string) stringfmt.Println(strings.ReplaceAll(s, "world", "Go")) //類似于 strings.Replace(s, "world", "Go", -1)
}
func Map
func Map(mapping func(rune) rune, s string) string
對字符串 s
中的每個 Unicode 字符 r
調用 mapping(r)
,返回映射后的字符,并組成新字符串。
若 mapping
返回 -1
,則會丟棄該字符。
func main() {s := "Hello 123"// 將所有數字去掉result := strings.Map(func(r rune) rune {if unicode.IsDigit(r) {return -1 // -1 表示丟棄這個字符}return r}, s)fmt.Println(result) // "Hello "//大小寫轉化result = strings.Map(func(r rune) rune {return unicode.ToUpper(r)}, s)fmt.Println(result) //HELLO 123str := "Go@lang! is #awesome$"// 替換 @, !, #, $ 為 *result = strings.Map(func(r rune) rune {switch r {case '@', '!', '#', '$':return '*'default:return r}}, str)fmt.Println(result) // "Go*lang* is *awesome*"
}
Map
適合對字符串做逐字符的自定義轉換或過濾。
func Trim
func Trim(s string, cutset string) string
用于去除字符串兩端的指定字符集(cutset
)中的字符。
func main() {s := " !hello world! "cutset := " !"// 去除兩端的空格和感嘆號result := strings.Trim(s, cutset)fmt.Println(result) // "hello world"
}
func TrimSpace
func TrimSpace(s string) string
去除字符串 s
開頭和結尾的空白字符(包括空格、制表符、換行等)。
func main() {s := " Hello Golang \n "fmt.Println(strings.TrimSpace(s)) // "Hello Golang"
}
func TrimFunc
func TrimFunc(s string, f func(rune) bool) string
根據自定義的判定函數(函數類型為 func(rune) bool
)去除字符串兩端的字符。
func main() {s := "123!Hello, Go!?!456"// 定義判定函數:如果字符不是字母,則返回 true,表示該字符需要被移除trimFunc := func(r rune) bool {return !unicode.IsLetter(r)}// 使用 TrimFunc 去除兩端非字母字符result := strings.TrimFunc(s, trimFunc)fmt.Println(result) // 輸出 "Hello, Go!?"//去除兩端的的數字trimFunc = func(r rune) bool {return unicode.IsDigit(r)}result = strings.TrimFunc(s, trimFunc)fmt.Println(result) // 輸出 "!Hello, Go!?!"}
func TrimLeft
func TrimLeft(s string, cutset string) string
從字符串 左側(即開頭)開始移除所有出現在 cutset
中的字符,直到遇到第一個不在 cutset
中的字符為止。
僅對字符串開頭部分進行處理,中間和結尾的字符不會受影響。
func main() {s := "!!!Hello, World!!!"cutset := "!"// 去除左側所有感嘆號leftTrimmed := strings.TrimLeft(s, cutset)fmt.Println(leftTrimmed) // 輸出: "Hello, World!!!"
}
func TrimLeftFunc
func TrimLeftFunc(s string, f func(rune) bool) string
從左側開始,移除連續滿足 f(rune) == true
的字符,直到遇到不滿足的字符后停止。
func main() {s := " Hello 123"// 移除左側空白result := strings.TrimLeftFunc(s, unicode.IsSpace)fmt.Println(result) // "Hello 123"
}
func TrimPrefix
func TrimPrefix(s, prefix string) string
若字符串 s
以 prefix
開頭,則去除該前綴并返回剩余部分;否則返回 s
本身。
func main() {s := "HelloWorld"fmt.Println(strings.TrimPrefix(s, "Hello")) // "World"fmt.Println(strings.TrimPrefix(s, "Go")) // "HelloWorld" (無變化)
}
func TrimRight
func TrimRight(s string, cutset string) string
TrimRight
從字符串 右側(即結尾)開始移除所有出現在 cutset
中的字符,直到遇到第一個不在 cutset
中的字符為止。
僅對字符串末尾部分進行處理,左側和中間的字符不會受影響。
func main() {s := "!!!Hello, World!!!"cutset := "!"// 去除右側所有感嘆號rightTrimmed := strings.TrimRight(s, cutset)fmt.Println(rightTrimmed) // 輸出: "!!!Hello, World"
}
func TrimRightFunc
func TrimRightFunc(s string, f func(rune) bool) string
從右側開始,移除連續滿足 f(rune) == true
的字符,直到遇到不滿足的字符后停止。
func main() {s := "Hello 123 "result := strings.TrimRightFunc(s, unicode.IsSpace)fmt.Println(result) // "Hello 123"
}
func TrimSuffix
func TrimSuffix(s, suffix string) string
若字符串 s
以 suffix
結尾,則去除該后綴并返回剩余部分;否則返回 s
本身。
func main() {s := "HelloWorld"fmt.Println(strings.TrimSuffix(s, "World")) // "Hello"fmt.Println(strings.TrimSuffix(s, "Go")) // "HelloWorld"
}
func Fields
func Fields(s string) []string
strings.Fields
根據 Unicode 空白字符將字符串分割成多個字段。空白字符包括空格、制表符、換行符等,函數會把連續的空白字符看作一個分隔符。
func main() {s := " hello\tworld\n Go 語言 "fields := strings.Fields(s)fmt.Println(fields) // 輸出: ["hello" "world" "Go" "語言"]
}
func FieldsFunc
func TrimSuffix(s, suffix string) string
strings.FieldsFunc
根據用戶提供的判定函數來分割字符串。這個函數接受一個 rune
參數,并返回 true
或 false
。當判定函數返回 true
時,該字符被視為分隔符。
// 定義一個函數,將所有非字母和非漢字的字符作為分隔符
func isNotLetter(r rune) bool {return !unicode.IsLetter(r) && !unicode.Is(unicode.Han, r)
}func main() {s := "hello,world!歡迎來到-Go語言."// 根據自定義規則分割字符串fields := strings.FieldsFunc(s, isNotLetter)fmt.Println(fields) // 輸出: ["hello" "world" "歡迎" "來到" "Go語言"]
}
func Split
func Split(s, sep string) []string
按分隔符 sep
拆分字符串 s
,返回 []string
。
- 若
sep
為空字符串""
,則將s
按單個字符拆分。 - 若
sep
在s
中不存在,則返回[s]
。
func main() {s := "a,b,c"fmt.Println(strings.Split(s, ",")) // ["a" "b" "c"]fmt.Println(strings.Split(s, "")) //[a , b , c]
}
func SplitN
func SplitN(s, sep string, n int) []string
按分隔符 sep
拆分字符串 s
,最多拆分 n
個部分,返回 []string
。
- 如果
n
> 0,則最多返回n
個子串。 - 如果
n
< 0,則拆分所有可能的子串。
func main() {s := "a,b,c,d"fmt.Println(strings.SplitN(s, ",", 2)) // ["a" "b,c,d"]fmt.Println(strings.SplitN(s, ",", -1)) //[a b c d]
}
func SplitAfter/func SplitAfterN
func SplitAfter(s, sep string) []string
func SplitAfterN(s, sep string, n int) []string
與 Split
/ SplitN
類似,但保留分隔符在拆分后的結果里。
func main() {s := "a,b,c"fmt.Println(strings.SplitAfter(s, ",")) // ["a," "b," "c"]fmt.Println(strings.SplitAfterN(s, ",", 2)) // ["a," "b,c"]
}
func Join
func Join(a []string, sep string) string
將 []string
用分隔符 sep
拼接成一個字符串。
func main() {words := []string{"Go", "is", "awesome"}fmt.Println(strings.Join(words, " ")) // "Go is awesome"
}
適用于把切片合并成一行文本,比如生成 CSV 行、命令行參數等。
總結:常見字符串操作的思維導圖
- 判斷/搜索
Contains/ContainsRune/ContainsAny
:是否包含子串或字符HasPrefix/HasSuffix
:是否以某前綴/后綴開頭或結尾Index/LastIndex
系列:查找子串或字符的第一次/最后一次出現位置Count
:統計子串出現次數EqualFold
:忽略大小寫判斷是否相等
- 大小寫轉換
ToLower/ToUpper/ToTitle
:將字符串全部轉為小寫/大寫/標題形式Title
:對每個單詞首字母做大寫處理
- 替換/映射
Replace/ReplaceAll
:將子串替換為新字符串Map
:對每個字符做自定義轉換,返回新字符串(可丟棄字符)
- 修剪(Trim)
Trim/TrimLeft/TrimRight
:去除指定字符集TrimSpace
:去除首尾空白字符TrimPrefix/TrimSuffix
:僅去除指定前綴/后綴TrimFunc
/TrimLeftFunc
/TrimRightFunc
:用自定義函數判斷是否需要修剪
- 拆分/拼接
Split/SplitN/SplitAfter/SplitAfterN
:按分隔符拆分字符串Fields/FieldsFunc
:按空白或自定義條件拆分Join
:將[]string
用分隔符拼接為一個字符串
- 重復
Repeat
:將字符串重復n
次