Skip to content

strings

Gói strings thực hiện các hàm đơn giản để thao tác chuỗi mã hóa UTF-8, nói đơn giản là gói công cụ thao tác chuỗi.

Tài liệu chính thức: strings package - strings - Go Packages

TIP

Go hỗ trợ native ký tự UTF8, tất cả các thao tác chuỗi đều được xây dựng trên nền tảng UTF8.

Nhập

go
import (
   "strings"
)

Dưới đây sẽ giải thích các hàm thường dùng thông qua ví dụ.

Sao chép chuỗi

go
func Clone(s string) string

Sẽ cấp phát bộ nhớ mới cho bản sao, nếu truyền vào chuỗi rỗng thì không cấp phát bộ nhớ và trả về chuỗi rỗng.

go
func TestClone(t *testing.T) {
   ori := "hello 世界"
   copys := strings.Clone(ori)
   fmt.Println(ori, copys)
   fmt.Println(&ori, &copys)
}
=== RUN   TestClone
hello 世界 hello 世界
0xc00005e5d0 0xc00005e5e0
--- PASS: TestClone (0.00s)
PASS

So sánh chuỗi

go
func Compare(a, b string) int

So sánh a với b theo thứ tự từ điển, nếu a>b trả về 1, a<b trả về -1, a=b trả về 0.

go
func TestCompare(t *testing.T) {
  fmt.Println(strings.Compare("abc", "abe"))
  fmt.Println(strings.Compare("abcd", "abe"))
  fmt.Println(strings.Compare("abijk", "abe"))
  fmt.Println(strings.Compare("abe", "abe"))
}
=== RUN   TestCompare
-1
-1
1
0
--- PASS: TestCompare (0.00s)
PASS

Chứa chuỗi

go
func Contains(s, substr string) bool

Kiểm tra xem chuỗi s có chứa chuỗi con substr không

go
func TestContains(t *testing.T) {
  fmt.Println(strings.Contains("abcdefg", "a"))
  fmt.Println(strings.Contains("abcdefg", "abc"))
  fmt.Println(strings.Contains("abcdefg", "ba"))
}
=== RUN   TestContains
true
true
false
--- PASS: TestContains (0.00s)
PASS
go
func ContainsAny(s, chars string) bool

Kiểm tra xem bất kỳ ký tự unicode nào trong chuỗi chars có nằm trong chuỗi s không, dịch ra là s có chứa bất kỳ chuỗi nào trong chars không

go
func TestContainsAny(t *testing.T) {
  fmt.Println(strings.ContainsAny("abcedfg", "bac"))
  fmt.Println(strings.ContainsAny("abcedfg", "gfdecba"))
}
=== RUN   TestContainsAny
true
--- PASS: TestContainsAny (0.00s)
PASS
go
func ContainsRune(s string, r rune) bool

Kiểm tra xem chuỗi s có chứa ký tự r không

go
func TestContainsRune(t *testing.T) {
   fmt.Println(strings.ContainsRune("abcedf", 'a'))
   fmt.Println(strings.ContainsRune("abcedf", 'b'))
   fmt.Println(strings.ContainsRune("你好世界", ''))
}
=== RUN   TestContainsRune
true
true
true
--- PASS: TestContainsRune (0.00s)
PASS

Số lần xuất hiện của chuỗi con

go
func Count(s, substr string) int

Trả về số lần xuất hiện của chuỗi con substr trong chuỗi s

go
func TestCount(t *testing.T) {
  fmt.Println(strings.Count("3.1415926", "1"))
  fmt.Println(strings.Count("there is a girl", "e"))
  fmt.Println(strings.Count("there is a girl", ""))
}
=== RUN   TestCount
2
2
16
--- PASS: TestCount (0.00s)
PASS

Xóa chuỗi con chỉ định

go
func Cut(s, sep string) (before, after string, found bool)

Xóa lần xuất hiện đầu tiên của chuỗi con sep trong s, và trả về kết quả sau khi xóa

  • before - Chuỗi trước vị trí chuỗi con bị xóa
  • after - Chuỗi sau vị trí chuỗi con bị xóa
  • found - Có tìm thấy chuỗi con không
go
func TestCut(t *testing.T) {
  show := func(s, sep string) {
    before, after, found := strings.Cut(s, sep)
    fmt.Printf("Cut(%q, %q) = %q, %q, %v\n", s, sep, before, after, found)
  }
  show("Hello world", " ")
  show("Hello world", "world")
  show("Hello world", "Hello")
  show("Hello world", "Hello world")
}
=== RUN   TestCut
Cut("Hello world", " ") = "Hello", "world", true
Cut("Hello world", "world") = "Hello ", "", true
Cut("Hello world", "Hello") = "", " world", true
Cut("Hello world", "Hello world") = "", "", true
--- PASS: TestCut (0.00s)
PASS

Bằng nhau bỏ qua chữ hoa thường

go
func EqualFold(s, t string) bool

Trả về xem chuỗi s và t có bằng nhau khi bỏ qua chữ hoa thường không

go
func TestEqualFold(t *testing.T) {
   fmt.Println(strings.EqualFold("你好", "你好"))
   fmt.Println(strings.EqualFold("Hello", "Hello"))
   fmt.Println(strings.EqualFold("Hello", "hELLO"))
}
=== RUN   TestEqualFold
true
true
true
--- PASS: TestEqualFold (0.00s)
PASS

Tách chuỗi

go
func Fields(s string) []string
go
func FieldsFunc(s string, f func(rune) bool) []string

Cái trước tách chuỗi dựa trên khoảng trắng, cái sau dựa trên giá trị trả về của hàm f để quyết định có tách chuỗi không.

go
func TestField(t *testing.T) {
   fmt.Printf("%q\n", strings.Fields(" a b c d e f g "))
   fmt.Printf("%q\n", strings.FieldsFunc("a,b,c,d,e,f,g", func(r rune) bool {
      return r == ','
   }))
}
=== RUN   TestField
["a" "b" "c" "d" "e" "f" "g"]
["a" "b" "c" "d" "e" "f" "g"]
--- PASS: TestField (0.00s)
PASS

Tìm tiền tố và hậu tố

go
func HasPrefix(s, prefix string) bool
go
func HasSuffix(s, suffix string) bool

Cái trước tìm tiền tố, cái sau tìm hậu tố, nếu quan tâm có thể xem triển khai mã nguồn ở đây, khá khéo léo.

go
func TestPreSuffix(t *testing.T) {
   str := "abbc cbba"
   fmt.Println(strings.HasPrefix(str, "abb"))
   fmt.Println(strings.HasSuffix(str, "bba"))
}
=== RUN   TestPreSuffix
true
true
--- PASS: TestPreSuffix (0.00s)
PASS

Vị trí chuỗi con

Trả về chỉ số của lần xuất hiện đầu tiên của chuỗi con

go
func Index(s, substr string) int

Trả về chỉ số của lần xuất hiện đầu tiên của chuỗi con

go
func IndexAny(s, chars string) int

Trả về chỉ số của lần xuất hiện đầu tiên của chuỗi con

go
func IndexRune(s string, r rune) int

Ví dụ

go
func TestIndex(t *testing.T) {
   fmt.Println(strings.Index("abcdefg", "bc"))
   fmt.Println(strings.IndexAny("abcdefg", "cb"))
   fmt.Println(strings.IndexRune("abcdefg", 'g'))
}
=== RUN   TestIndex
1
1
6
--- PASS: TestIndex (0.00s)
PASS

Trả về chỉ số của lần xuất hiện cuối cùng của chuỗi con

go
func LastIndex(s, substr string) int

Trả về chỉ số của bất kỳ ký tự nào của chuỗi con xuất hiện lần cuối cùng

go
func LastIndexAny(s, chars string) int

Ví dụ

go
func TestLastIndex(t *testing.T) {
  fmt.Println(strings.LastIndex("abcdefga", "a"))
  fmt.Println(strings.LastIndexAny("abcdefghisa", "ba"))
}

Duyệt và thay thế chuỗi

Map trả về bản sao của chuỗi s và sửa đổi tất cả các ký tự của chuỗi s theo hàm ánh xạ. Nếu ánh xạ trả về giá trị âm thì xóa ký tự đó khỏi chuỗi, không thay thế

go
func Map(mapping func(rune) rune, s string) string

Ví dụ

go
func TestMap(t *testing.T) {
   fmt.Println(strings.Map(func(r rune) rune {
      return r - 32
   }, "abcdefghijk"))
   fmt.Println(strings.Map(func(r rune) rune {
      return r + 32
   }, "ABCDEFGHIJK"))
   fmt.Println(strings.Map(func(r rune) rune {
      if r < 'F' {
         return -1
      } else {
         return r
      }
   }, "ABCDEFGHIJK"))
}

Đầu ra

text
=== RUN   TestMap
ABCDEFGHIJK
abcdefghijk
FGHIJK
--- PASS: TestMap (0.00s)
PASS

Sao chép chuỗi nhiều lần

Sao chép chuỗi theo Count đã cho, nếu là số âm sẽ gây ra panic

go
func Repeat(s string, count int) string

Ví dụ

go
func TestRepeat(t *testing.T) {
   fmt.Println(strings.Repeat("a", 10))
   fmt.Println(strings.Repeat("abc", 10))
}

Đầu ra

=== RUN   TestRepeat
aaaaaaaaaa
abcabcabcabcabcabcabcabcabcabc
--- PASS: TestRepeat (0.00s)
PASS

Thay thế chuỗi

s là chuỗi nguồn, old là phần cần được thay thế, new là phần thay thế cho old, n là số lần thay thế, n nhỏ hơn 0 biểu thị không giới hạn số lần thay thế.

go
func Replace(s, old, new string, n int) string

Ví dụ

go
func TestReplace(t *testing.T) {
   fmt.Println(strings.Replace("Hello this is golang", "golang", "c++", 1))
   fmt.Println(strings.Replace("Hello this is golang", "o", "c", -1))
   fmt.Println(strings.Replace("Hello this is golang", "o", "c", 1))
}

Đầu ra

=== RUN   TestReplace
Hello this is c++
Hellc this is gclang
Hellc this is golang
--- PASS: TestReplace (0.00s)
PASS

Hàm tiện lợi của Replace, tương đương với stings.Replace(s,old,new,-1)

go
func ReplaceAll(s, old, new string) string

Ví dụ

go
func TestReplaceAll(t *testing.T) {
  fmt.Println(strings.ReplaceAll("Hello this is golang", "o", "c++"))
}

Đầu ra

=== RUN   TestReplaceAll
Hellc++ this is gc++lang
--- PASS: TestReplaceAll (0.00s)
PASS

Tách chuỗi

Tách chuỗi s thành slice chuỗi dựa trên chuỗi con sep

go
func Split(s, sep string) []string

Tách chuỗi s thành slice chuỗi dựa trên chuỗi con sep, số lần tách được quyết định bởi n

go
func SplitN(s, sep string, n int) []string

Tách chuỗi s thành slice chuỗi chứa các phần tử chuỗi có chứa sep

go
func SplitAfter(s, sep string) []string

Tách chuỗi s thành slice chuỗi chứa các phần tử chuỗi có chứa sep, số lần tách được quyết định bởi n

go
func SplitAfterN(s, sep string, n int) []string

Ví dụ

go
func TestSplit(t *testing.T) {
   fmt.Printf("%q\n", strings.Split("this is go language", " "))
   fmt.Printf("%q\n", strings.SplitN("this is go language", " ", 2))
   fmt.Printf("%q\n", strings.SplitAfter("this is go language", " "))
   fmt.Printf("%q\n", strings.SplitAfterN("this is go language", " ", 2))
}

Đầu ra

=== RUN   TestSplit
["this" "is" "go" "language"]
["this" "is go language"]
["this " "is " "go " "language"]
["this " "is go language"]
--- PASS: TestSplit (0.00s)
PASS

Chuyển đổi chữ hoa chữ thường

Chuyển chuỗi chữ hoa tiếng Anh thành chuỗi chữ thường

go
func ToLower(s string) string

Dựa vào unicode.SpecialCase của ngôn ngữ tương ứng được truyền vào, chuyển thành chuỗi chữ thường của ngôn ngữ tương ứng

go
func ToLowerSpecial(c unicode.SpecialCase, s string) string

Chuyển chuỗi tiếng Anh thành chuỗi chữ hoa

go
func ToUpper(s string) string

Dựa vào unicode.SpecialCase của ngôn ngữ tương ứng được truyền vào, chuyển thành chuỗi chữ hoa của ngôn ngữ tương ứng

go
func ToUpperSpecial(c unicode.SpecialCase, s string) string

Ví dụ

go
func TestLowerAndUpper(t *testing.T) {
   fmt.Println(strings.ToLower("My name is jack,Nice to meet you!"))
   fmt.Println(strings.ToLowerSpecial(unicode.TurkishCase, "Önnek İş"))
   fmt.Println(strings.ToUpper("My name is jack,Nice to meet you!"))
   fmt.Println(strings.ToUpperSpecial(unicode.TurkishCase, "örnek iş"))
}

Đầu ra

=== RUN   TestLowerAndUpper
my name is jack,nice to meet you!
önnek iş
MY NAME IS JACK,NICE TO MEET YOU!
ÖRNEK İŞ
--- PASS: TestLowerAndUpper (0.00s)
PASS

Cắt chuỗi

Cắt hai đầu chuỗi, xóa các chuỗi con khớp bất kỳ của cutset

go
func Trim(s, cutset string) string

Cắt đầu trái chuỗi, xóa các chuỗi con khớp bất kỳ của cutset

go
func TrimLeft(s, cutset string) string

Cắt tiền tố đầu trái chuỗi, xóa các chuỗi con khớp của cutset, nếu không khớp sẽ trả về chuỗi s

go
func TrimPrefix(s, suffix string) string

Cắt đầu phải chuỗi, xóa các chuỗi con khớp bất kỳ của cutset

go
func TrimRight(s, cutset string) string

Cắt hậu tố đầu phải chuỗi, xóa các chuỗi con khớp của cutset, nếu không khớp sẽ trả về chuỗi s

go
func TrimSuffix(s, suffix string) string

Ví dụ

go
func TestTrim(t *testing.T) {
  fmt.Println(strings.Trim("!!this is a test statement!!", "!!!"))
  fmt.Println(strings.TrimLeft("!!this is a test statement!!", "!!!"))
  fmt.Println(strings.TrimRight("!!this is a test statement!!", "!!!"))
  fmt.Println(strings.TrimPrefix("!!this is a test statement!!", "!!!"))
  fmt.Println(strings.TrimSuffix("!!this is a test statement!!", "!!!"))
}

Đầu ra

=== RUN   TestTrim
this is a test statement
this is a test statement!!
!!this is a test statement
!!this is a test statement!!
!!this is a test statement!!
--- PASS: TestTrim (0.00s)
PASS

Builder chuỗi

Builder chuỗi tiết kiệm bộ nhớ hơn so với thao tác chuỗi trực tiếp.

go
type Builder struct {
  // Các trường nội bộ không được tiết lộ ra ngoài
}

Ví dụ

go
func TestBuilder(t *testing.T) {
   builder := strings.Builder{}
   builder.WriteString("hello")
   builder.WriteString(" world")
   fmt.Println(builder.Len())
   fmt.Println(builder.String())
}

Đầu ra

=== RUN   TestBuilder
11
hello world
--- PASS: TestBuilder (0.00s)
PASS

TIP

Đừng cố gắng truyền Builder như một giá trị, ví dụ khi truyền strings.Builder làm tham số hàm, chương trình sẽ panic

strings: illegal use of non-zero Builder copied by value

Bên trong có đoạn mã sau

go
type Builder struct {
  addr *Builder //Địa chỉ của chính nó
  buf  []byte
}

func (b *Builder) copyCheck() {
   if b.addr == nil {
      b.addr = (*Builder)(noescape(unsafe.Pointer(b)))
   } else if b.addr != b {
      panic("strings: illegal use of non-zero Builder copied by value")
   }
}

Khi sao chép giá trị Builder, cũng sao chép con trỏ của slice nội bộ, hai Builder khi ghi chuỗi đều thao tác trên cùng một slice, đây cũng là lý do tại sao không cho phép sao chép giá trị.

Replacer chuỗi

Replacer chuyên dùng để thay thế chuỗi

go
func NewReplacer(oldnew ...string) *Replacer

Ví dụ

go
func TestReplacer(t *testing.T) {
  r := strings.NewReplacer("<", "<", ">", ">")
  fmt.Println(r.Replace("This is <b>HTML</b>!"))
}

Đầu ra

This is <b>HTML</b>!

Reader chuỗi

Reader triển khai các interface io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.RuneReader, io.RuneScanner, io.Seeker, và io.WriterTo.

go
func NewReader(s string) *Reader

Ví dụ

go
func TestReader(t *testing.T) {
   reader := strings.NewReader("abcdefghijk")
   buffer := make([]byte, 20, 20)
   read, err := reader.Read(buffer)
   if err != nil {
      log.Panic(err)
   }
   fmt.Println(read)
   fmt.Println(string(buffer))
}

Đầu ra

=== RUN   TestReader
11
abcdefghijk
--- PASS: TestReader (0.00s)
PASS

Golang by www.golangdev.cn edit