strings
El paquete strings implementa funciones simples para operar con cadenas codificadas en UTF-8. En resumen, es un paquete de herramientas para operar con cadenas.
Documentación oficial: strings package - strings - Go Packages
TIP
Go admite de forma nativa caracteres UTF8, y todas las operaciones de cadenas se basan en UTF8.
Importar
import (
"strings"
)A continuación se explicarán las funciones comunes con ejemplos.
Clonar cadena
func Clone(s string) stringAsignará una nueva memoria para la copia. Si se pasa una cadena vacía, no asignará memoria y devolverá una cadena vacía.
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 cadenas
func Compare(a, b string) intCompara las cadenas a y b en orden lexicográfico. Si a>b, devuelve 1; si a<b, devuelve -1; si a=b, devuelve 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)
PASSContiene cadena
func Contains(s, substr string) boolDetermina si una cadena s contiene una subcadena 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) boolDetermina si cualquier carácter Unicode de la cadena chars está en la cadena s. Traducido, es si s contiene cualquier cadena dentro 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) boolDetermina si la cadena s contiene el carácter 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)
PASSNúmero de apariciones de subcadena
func Count(s, substr string) intDevuelve el número de veces que aparece la subcadena substr en la cadena 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)
PASSEliminar subcadena especificada
func Cut(s, sep string) (before, after string, found bool)Elimina la primera aparición de la subcadena sep en s y devuelve el resultado después de eliminar
before- La cadena antes de la posición de la subcadena eliminadaafter- La cadena después de la posición de la subcadena eliminadafound- Si se encontró la subcadena
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)
PASSIgualdad ignorando mayúsculas/minúsculas
func EqualFold(s, t string) boolDevuelve si las cadenas s y t son iguales ignorando mayú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 cadena
func Fields(s string) []stringfunc FieldsFunc(s string, f func(rune) bool) []stringEl primero divide la cadena por espacios, el segundo decide si dividir la cadena según el valor de retorno de la función f.
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 prefijo/sufijo
func HasPrefix(s, prefix string) boolfunc HasSuffix(s, suffix string) boolEl primero busca el prefijo, el segundo busca el sufijo. Si está interesado, puede ver la implementación del código fuente aquí, es bastante ingeniosa.
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)
PASSPosición de la subcadena
Devuelve el índice de la primera aparición de la subcadena
func Index(s, substr string) intDevuelve el índice de la primera aparición de la subcadena
func IndexAny(s, chars string) intDevuelve el índice de la primera aparición de la subcadena
func IndexRune(s string, r rune) intEjemplo
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)
PASSDevuelve el índice de la última aparición de la subcadena
func LastIndex(s, substr string) intDevuelve el índice de cualquier carácter de la última aparición de la subcadena
func LastIndexAny(s, chars string) intEjemplo
func TestLastIndex(t *testing.T) {
fmt.Println(strings.LastIndex("abcdefga", "a"))
fmt.Println(strings.LastIndexAny("abcdefghisa", "ba"))
}Iterar y reemplazar cadena
Map devuelve una copia de la cadena s y modifica todos los caracteres de la cadena s según la función de mapeo. Si el mapeo devuelve un valor negativo, el carácter se elimina de la cadena sin reemplazo
func Map(mapping func(rune) rune, s string) stringEjemplo
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"))
}Salida
=== RUN TestMap
ABCDEFGHIJK
abcdefghijk
FGHIJK
--- PASS: TestMap (0.00s)
PASSDuplicar cadena
Duplica la cadena según el Count dado. Si es negativo, causará panic
func Repeat(s string, count int) stringEjemplo
func TestRepeat(t *testing.T) {
fmt.Println(strings.Repeat("a", 10))
fmt.Println(strings.Repeat("abc", 10))
}Salida
=== RUN TestRepeat
aaaaaaaaaa
abcabcabcabcabcabcabcabcabcabc
--- PASS: TestRepeat (0.00s)
PASSReemplazar cadena
s es la cadena de origen, old es la parte que se va a reemplazar, new es la parte que reemplaza a old, n es el número de reemplazos. Si n es menor que 0, significa que no hay límite en el número de reemplazos.
func Replace(s, old, new string, n int) stringEjemplo
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))
}Salida
=== RUN TestReplace
Hello this is c++
Hellc this is gclang
Hellc this is golang
--- PASS: TestReplace (0.00s)
PASSFunción conveniente de Replace, equivalente a strings.Replace(s, old, new, -1)
func ReplaceAll(s, old, new string) stringEjemplo
func TestReplaceAll(t *testing.T) {
fmt.Println(strings.ReplaceAll("Hello this is golang", "o", "c++"))
}Salida
=== RUN TestReplaceAll
Hellc++ this is gc++lang
--- PASS: TestReplaceAll (0.00s)
PASSSeparar cadena
Divide la cadena s en un slice de cadenas según la subcadena sep
func Split(s, sep string) []stringDivide la cadena s en un slice de cadenas según la subcadena sep, el número de divisiones está determinado por n
func SplitN(s, sep string, n int) []stringDivide la cadena s en un slice de cadenas que contienen la subcadena sep
func SplitAfter(s, sep string) []stringDivide la cadena s en un slice de cadenas que contienen la subcadena sep, el número de divisiones está determinado por n
func SplitAfterN(s, sep string, n int) []stringEjemplo
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))
}Salida
=== RUN TestSplit
["this" "is" "go" "language"]
["this" "is go language"]
["this " "is " "go " "language"]
["this " "is go language"]
--- PASS: TestSplit (0.00s)
PASSConversión de mayúsculas/minúsculas
Convierte la cadena en inglés a minúsculas
func ToLower(s string) stringConvierte a minúsculas según el unicode.SpecialCase del idioma correspondiente
func ToLowerSpecial(c unicode.SpecialCase, s string) stringConvierte la cadena en inglés a mayúsculas
func ToUpper(s string) stringConvierte a mayúsculas según el unicode.SpecialCase del idioma correspondiente
func ToUpperSpecial(c unicode.SpecialCase, s string) stringEjemplo
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ş"))
}Salida
=== 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)
PASSRecortar cadena
Recorta ambos extremos de la cadena, eliminando cualquier subcadena que coincida con cutset
func Trim(s, cutset string) stringRecorta el extremo izquierdo de la cadena, eliminando cualquier subcadena que coincida con cutset
func TrimLeft(s, cutset string) stringRecorta el prefijo del extremo izquierdo de la cadena, eliminando la subcadena que coincide con cutset. Si no coincide, devuelve la cadena s
func TrimPrefix(s, suffix string) stringRecorta el extremo derecho de la cadena, eliminando cualquier subcadena que coincida con cutset
func TrimRight(s, cutset string) stringRecorta el sufijo del extremo derecho de la cadena, eliminando la subcadena que coincide con cutset. Si no coincide, devuelve la cadena s
func TrimSuffix(s, suffix string) stringEjemplo
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!!", "!!!"))
}Salida
=== 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 cadenas
El Builder de cadenas ahorra más memoria que operar directamente con cadenas.
type Builder struct {
// Los campos internos no se exponen externamente
}Ejemplo
func TestBuilder(t *testing.T) {
builder := strings.Builder{}
builder.WriteString("hello")
builder.WriteString(" world")
fmt.Println(builder.Len())
fmt.Println(builder.String())
}Salida
=== RUN TestBuilder
11
hello world
--- PASS: TestBuilder (0.00s)
PASSTIP
No intente pasar Builder como un valor, por ejemplo, al pasar strings.Builder como parámetro de función, el programa entrará en panic
strings: illegal use of non-zero Builder copied by valueInternamente tiene el siguiente código
type Builder struct {
addr *Builder // Dirección propia
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")
}
}Al copiar el valor de Builder, también se copia el puntero del slice interno. Dos Builder están operando en el mismo slice al escribir cadenas, por eso no se permite la copia por valor.
Replacer de cadenas
Replacer se usa para reemplazar cadenas
func NewReplacer(oldnew ...string) *ReplacerEjemplo
func TestReplacer(t *testing.T) {
r := strings.NewReplacer("<", "<", ">", ">")
fmt.Println(r.Replace("This is <b>HTML</b>!"))
}Salida
This is <b>HTML</b>!Reader de cadenas
Reader implementa las interfaces io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.RuneReader, io.RuneScanner, io.Seeker y io.WriterTo.
func NewReader(s string) *ReaderEjemplo
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))
}Salida
=== RUN TestReader
11
abcdefghijk
--- PASS: TestReader (0.00s)
PASS