strings
O pacote strings implementa funções simples para operar strings codificadas em UTF-8. Em resumo, é um pacote de ferramentas para operar strings.
Documentação oficial: strings package - strings - Go Packages
TIP
Go suporta nativamente caracteres UTF8, e todas as operações de strings são baseadas em UTF8.
Importação
import (
"strings"
)Abaixo serão explicadas as funções comumente usadas através de exemplos.
Clonar String
func Clone(s string) stringAloca uma nova memória para a cópia. Se uma string vazia for passada, nenhuma memória será alocada e uma string vazia será retornada.
func TestClone(t *testing.T) {
ori := "hello 世界"
copys := strings.Clone(ori)
fmt.Println(ori, copys)
fmt.Println(&ori, ©s)
}=== RUN TestClone
hello 世界 hello 世界
0xc00005e5d0 0xc00005e5e0
--- PASS: TestClone (0.00s)
PASSComparar Strings
func Compare(a, b string) intCompara a string a com b em ordem lexicográfica. Se a>b, retorna 1; se a<b, retorna -1; se a=b, retorna 0.
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)
PASSConter String
func Contains(s, substr string) boolVerifica se uma string s contém uma substring substr.
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)
PASSfunc ContainsAny(s, chars string) boolVerifica se qualquer caractere Unicode da string chars está dentro da string s. Em outras palavras, verifica se s contém qualquer caractere de chars.
func TestContainsAny(t *testing.T) {
fmt.Println(strings.ContainsAny("abcedfg", "bac"))
fmt.Println(strings.ContainsAny("abcedfg", "gfdecba"))
}=== RUN TestContainsAny
true
--- PASS: TestContainsAny (0.00s)
PASSfunc ContainsRune(s string, r rune) boolVerifica se a string s contém o caractere r.
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)
PASSContagem de Ocorrências de Substring
func Count(s, substr string) intRetorna o número de vezes que a substring substr aparece na string s.
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)
PASSRemover Substring Especificada
func Cut(s, sep string) (before, after string, found bool)Remove a primeira ocorrência da substring sep em s e retorna o resultado após a remoção.
before- A string antes da posição da substring removidaafter- A string depois da posição da substring removidafound- Se a substring foi encontrada
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)
PASSIgualdade Ignorando Maiúsculas/Minúsculas
func EqualFold(s, t string) boolRetorna se as strings s e t são iguais ignorando maiúsculas/minúsculas.
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)
PASSDividir String
func Fields(s string) []stringfunc FieldsFunc(s string, f func(rune) bool) []stringO primeiro divide a string por espaços, o segundo usa o valor de retorno da função f para decidir se divide a string.
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)
PASSBuscar Prefixo e Sufixo
func HasPrefix(s, prefix string) boolfunc HasSuffix(s, suffix string) boolO primeiro busca prefixo, o segundo busca sufixo. Se interessar, você pode ver a implementação do código-fonte aqui, que é bastante engenhosa.
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)
PASSPosição da Substring
Retorna o índice da primeira ocorrência da substring:
func Index(s, substr string) intRetorna o índice da primeira ocorrência de qualquer caractere da substring:
func IndexAny(s, chars string) intRetorna o índice da primeira ocorrência do caractere rune:
func IndexRune(s string, r rune) intExemplo:
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)
PASSRetorna o índice da última ocorrência da substring:
func LastIndex(s, substr string) intRetorna o índice da última ocorrência de qualquer caractere da substring:
func LastIndexAny(s, chars string) intExemplo:
func TestLastIndex(t *testing.T) {
fmt.Println(strings.LastIndex("abcdefga", "a"))
fmt.Println(strings.LastIndexAny("abcdefghisa", "ba"))
}Percorrer e Substituir String
Map retorna uma cópia da string s e modifica todos os caracteres da string s de acordo com a função de mapeamento. Se o mapeamento retornar um valor negativo, o caractere será removido da string sem substituição.
func Map(mapping func(rune) rune, s string) stringExemplo:
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"))
}Saída:
=== RUN TestMap
ABCDEFGHIJK
abcdefghijk
FGHIJK
--- PASS: TestMap (0.00s)
PASSRepetir String
Repete a string de acordo com o count fornecido. Se for negativo, causará panic.
func Repeat(s string, count int) stringExemplo:
func TestRepeat(t *testing.T) {
fmt.Println(strings.Repeat("a", 10))
fmt.Println(strings.Repeat("abc", 10))
}Saída:
=== RUN TestRepeat
aaaaaaaaaa
abcabcabcabcabcabcabcabcabcabc
--- PASS: TestRepeat (0.00s)
PASSSubstituir String
s é a string de origem, old é a parte a ser substituída, new é a parte que substitui old, n é o número de substituições. Se n for menor que 0, significa que não há limite no número de substituições.
func Replace(s, old, new string, n int) stringExemplo:
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))
}Saída:
=== RUN TestReplace
Hello this is c++
Hellc this is gclang
Hellc this is golang
--- PASS: TestReplace (0.00s)
PASSFunção conveniente do Replace, equivalente a strings.Replace(s, old, new, -1):
func ReplaceAll(s, old, new string) stringExemplo:
func TestReplaceAll(t *testing.T) {
fmt.Println(strings.ReplaceAll("Hello this is golang", "o", "c++"))
}Saída:
=== RUN TestReplaceAll
Hellc++ this is gc++lang
--- PASS: TestReplaceAll (0.00s)
PASSSeparar String
Separa a string s em um slice de strings de acordo com a substring sep:
func Split(s, sep string) []stringSepara a string s em um slice de strings de acordo com a substring sep, onde o número de separações é determinado por n:
func SplitN(s, sep string, n int) []stringSepara a string s em um slice de strings contendo elementos de string com sep de acordo com a substring sep:
func SplitAfter(s, sep string) []stringSepara a string s em um slice de strings contendo elementos de string com sep de acordo com a substring sep, onde o número de separações é determinado por n:
func SplitAfterN(s, sep string, n int) []stringExemplo:
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))
}Saída:
=== RUN TestSplit
["this" "is" "go" "language"]
["this" "is go language"]
["this " "is " "go " "language"]
["this " "is go language"]
--- PASS: TestSplit (0.00s)
PASSConversão de Maiúsculas/Minúsculas
Converte string em inglês para minúsculas:
func ToLower(s string) stringConverte para minúsculas de acordo com o unicode.SpecialCase do idioma correspondente passado:
func ToLowerSpecial(c unicode.SpecialCase, s string) stringConverte string em inglês para maiúsculas:
func ToUpper(s string) stringConverte para maiúsculas de acordo com o unicode.SpecialCase do idioma correspondente passado:
func ToUpperSpecial(c unicode.SpecialCase, s string) stringExemplo:
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ş"))
}Saída:
=== 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)
PASSAparar String
Apara as extremidades da string, removendo qualquer substring que corresponda a cutset:
func Trim(s, cutset string) stringApara a extremidade esquerda da string, removendo qualquer substring que corresponda a cutset:
func TrimLeft(s, cutset string) stringApara o prefixo da extremidade esquerda da string, removendo a substring que corresponde a cutset. Se não corresponder, retorna a string s:
func TrimPrefix(s, suffix string) stringApara a extremidade direita da string, removendo qualquer substring que corresponda a cutset:
func TrimRight(s, cutset string) stringApara o sufixo da extremidade direita da string, removendo a substring que corresponde a cutset. Se não corresponder, retorna a string s:
func TrimSuffix(s, suffix string) stringExemplo:
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!!", "!!!"))
}Saída:
=== 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)
PASSBuilder de Strings
O Builder de strings é mais econômico em memória do que operar strings diretamente.
type Builder struct {
// Campos internos não são expostos externamente
}Exemplo:
func TestBuilder(t *testing.T) {
builder := strings.Builder{}
builder.WriteString("hello")
builder.WriteString(" world")
fmt.Println(builder.Len())
fmt.Println(builder.String())
}Saída:
=== RUN TestBuilder
11
hello world
--- PASS: TestBuilder (0.00s)
PASSTIP
Não tente passar Builder como valor, por exemplo, ao passar strings.Builder como parâmetro de função, o programa causará panic:
strings: illegal use of non-zero Builder copied by valueInternamente há o seguinte código:
type Builder struct {
addr *Builder // Endereço próprio
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")
}
}Ao copiar Builder por valor, também copia o ponteiro do slice interno. Dois Builder estarão operando no mesmo slice ao escrever strings, é por isso que a cópia por valor não é permitida.
Replacer de Strings
Replacer é usado para substituir strings:
func NewReplacer(oldnew ...string) *ReplacerExemplo:
func TestReplacer(t *testing.T) {
r := strings.NewReplacer("<", "<", ">", ">")
fmt.Println(r.Replace("This is <b>HTML</b>!"))
}Saída:
This is <b>HTML</b>!Reader de Strings
Reader implementa as interfaces io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.RuneReader, io.RuneScanner, io.Seeker e io.WriterTo.
func NewReader(s string) *ReaderExemplo:
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))
}Saída:
=== RUN TestReader
11
abcdefghijk
--- PASS: TestReader (0.00s)
PASS