Go strings 套件介紹
官方文件:strings - pkg.go.dev
strings 是 Go 標準庫的一員,用來操作 UTF-8 編碼字串。
關於 Go 中 UTF-8 字串的說明可參考:Strings, bytes, runes and characters in Go。
概述
- 套件路徑:
strings - 用途:字串搜尋、比較、切割、替換、大小寫、trim、高效組字串等
- 編碼:以 UTF-8 為準,函式多數以 位元組 index 回傳(不是 rune index)
函式分類
搜尋與包含
| 函式 | 說明 |
|---|---|
Contains(s, substr string) bool | 是否包含子字串 substr |
ContainsAny(s, chars string) bool | 是否包含 chars 中任一字元 |
ContainsRune(s string, r rune) bool | 是否包含某個 Unicode 碼點 |
ContainsFunc(s string, f func(rune) bool) bool | 是否有字元滿足 f(Go 1.21+) |
HasPrefix(s, prefix string) bool | 是否以 prefix 開頭 |
HasSuffix(s, suffix string) bool | 是否以 suffix 結尾 |
索引(回傳第一個/最後一個位置,無則 -1)
| 函式 | 說明 |
|---|---|
Index(s, substr string) int | 子字串第一次出現的 index |
LastIndex(s, substr string) int | 子字串最後一次出現的 index |
IndexByte(s string, c byte) int | 某 byte 第一次出現 |
LastIndexByte(s string, c byte) int | 某 byte 最後一次出現 |
IndexRune(s string, r rune) int | 某 rune 第一次出現 |
IndexAny(s, chars string) int | chars 中任一字元第一次出現 |
LastIndexAny(s, chars string) int | chars 中任一字元最後一次出現 |
IndexFunc(s string, f func(rune) bool) int | 第一個滿足 f 的字元 index |
LastIndexFunc(s string, f func(rune) bool) int | 最後一個滿足 f 的字元 index |
比較
| 函式 | 說明 |
|---|---|
Compare(a, b string) int | 字典序比較:0 相等、-1 a<b、+1 a>b;一般用 == / < / > 即可 |
EqualFold(s, t string) bool | 不區分大小寫的相等(簡單 Unicode case-folding) |
切割與組合
| 函式 | 說明 |
|---|---|
Split(s, sep string) []string | 以 sep 切開,回傳子字串 slice |
SplitN(s, sep string, n int) []string | 最多切 n 段 |
SplitAfter(s, sep string) []string | 切在 sep 後面,保留分隔符 |
SplitAfterN(s, sep string, n int) []string | 同上,最多 n 段 |
SplitSeq(s, sep string) iter.Seq[string] | 迭代器版 Split(Go 1.24+) |
SplitAfterSeq, FieldsSeq, FieldsFuncSeq | 對應的迭代器版本 |
Cut(s, sep string) (before, after string, found bool) | 依第一個 sep 切成前後兩段(Go 1.18+) |
CutPrefix(s, prefix string) (after string, found bool) | 去掉前綴(Go 1.20+) |
CutSuffix(s, suffix string) (before string, found bool) | 去掉後綴(Go 1.20+) |
Fields(s string) []string | 依空白切開(unicode.IsSpace) |
FieldsFunc(s string, f func(rune) bool) []string | 依自訂 f 切開 |
Lines(s string) iter.Seq[string] | 依換行迭代每一行(Go 1.24+) |
Join(elems []string, sep string) string | 用 sep 把多個字串接成一個 |
替換與計數
| 函式 | 說明 |
|---|---|
Replace(s, old, new string, n int) string | 替換前 n 次(n < 0 表示全部) |
ReplaceAll(s, old, new string) string | 替換所有(Go 1.12+) |
Count(s, substr string) int | 不重疊出現次數;substr == "" 時回傳 1+len(runes) |
大小寫與字元轉換
| 函式 | 說明 |
|---|---|
ToUpper(s string) string | 全轉大寫 |
ToLower(s string) string | 全轉小寫 |
ToTitle(s string) string | Unicode title case |
ToUpperSpecial(c unicode.SpecialCase, s string) string | 依特殊規則大寫(如土耳其語) |
ToLowerSpecial, ToTitleSpecial | 同上,小寫/title |
Title(s string) string | 已棄用,建議用 golang.org/x/text/cases |
Map(mapping func(rune) rune, s string) string | 每個 rune 經 mapping 轉換;回傳負值則刪除該字元 |
Trim(去頭尾)
| 函式 | 說明 |
|---|---|
TrimSpace(s string) string | 去掉頭尾空白(unicode.IsSpace) |
Trim(s, cutset string) string | 去掉頭尾在 cutset 內的字元 |
TrimLeft, TrimRight | 只去左/右 |
TrimPrefix(s, prefix string) string | 只去掉前綴(沒有前綴就原樣回傳) |
TrimSuffix(s, suffix string) string | 只去掉後綴 |
TrimFunc, TrimLeftFunc, TrimRightFunc | 用 func(rune) bool 決定要 trim 的字元 |
其他工具
| 函式 | 說明 |
|---|---|
Repeat(s string, count int) string | 重複 s 共 count 次 |
Clone(s string) string | 複製成新配置的字串(Go 1.18+),大字串取子串時可省記憶體 |
ToValidUTF8(s, replacement string) string | 將無效 UTF-8 序列替換成 replacement(Go 1.13+) |
型別
Builder(Go 1.10+)
用來高效組字串,減少記憶體複製。
WriteString(s string) (int, error)Write(p []byte) (int, error)、WriteByte(c byte)、WriteRune(r rune)String() string:取得組好的字串Len() int、Cap() int、Grow(n int)、Reset()
零值即可使用,不要複製已使用過的 Builder。
Reader
把字串當成 io.Reader 來讀。
NewReader(s string) *Reader- 實作:
io.Reader,io.ReaderAt,io.ByteReader,io.RuneReader,io.Seeker,io.WriterTo等 Len()、Size()、Reset(s string)等
Replacer
多組「舊→新」替換,可重複使用、goroutine 安全。
NewReplacer(oldnew ...string) *Replacer:參數為old1, new1, old2, new2, ...(奇數個會 panic)Replace(s string) stringWriteString(w io.Writer, s string) (n int, err error)
簡單範例
package main
import (
"fmt"
"strings"
)
func main() {
// 搜尋與包含
fmt.Println(strings.Contains("seafood", "foo")) // true
fmt.Println(strings.Index("chicken", "ken")) // 4
fmt.Println(strings.HasPrefix("Gopher", "Go")) // true
// Cut:依第一個分隔符切成兩段
before, after, ok := strings.Cut("Gopher", "ph")
fmt.Println(before, after, ok) // Go er true
// 切割與組合
fmt.Println(strings.Split("a,b,c", ",")) // [a b c]
fmt.Println(strings.Join([]string{"a", "b"}, "-")) // a-b
fmt.Println(strings.Fields(" foo bar baz ")) // [foo bar baz]
// 替換
fmt.Println(strings.ReplaceAll("oink oink", "oink", "moo")) // moo moo
// Trim
fmt.Println(strings.TrimSpace(" \t\n Hello \n\t ")) // Hello
// Builder
var b strings.Builder
b.WriteString("Hello")
b.WriteString(", ")
b.WriteString("World")
fmt.Println(b.String()) // Hello, World
}
注意事項
- 索引是 byte 位置:
Index、LastIndex等回傳的是位元組 index,不是 rune 數;若需「第幾個字元」要自己用utf8或 range 處理。 - 空字串:
Contains(s, "")為true;Count(s, "")為1 + 字元數。 Title已棄用:需依單字轉 title case 時建議用golang.org/x/text/cases。EqualFold:不做完整 Unicode case-folding,例如ß與ss會是false。
完整 API 與範例請以 pkg.go.dev/strings 為準。