Информацию о строках UTF-8 в Go см. на сайте https://blog.golang.org/strings.
Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.
Описание пакета string языка программирования Go
- 1: Функции пакета string языка программирования Go
- 2: Описание типов пакета string языка программирования Go
1 - Функции пакета string языка программирования Go
func Clone
func Clone(s string) string
Clone возвращает новую копию s. Оно гарантирует создание копии s в новом выделении памяти, что может быть важно при сохранении только небольшой подстроки из гораздо более длинной строки.
Использование Clone может помочь таким программам использовать меньше памяти.
Конечно, поскольку использование Clone создает копию, чрезмерное использование Clone может привести к увеличению потребления памяти программами. Обычно Clone следует использовать редко и только в тех случаях, когда профилирование показывает, что это необходимо. Для строк длиной ноль будет возвращена строка "" и выделение памяти не будет производиться.
Пример
package main
import (
"fmt"
"strings"
"unsafe"
)
func main() {
s := "abc"
clone := strings.Clone(s)
fmt.Println(s == clone)
fmt.Println(unsafe.StringData(s) == unsafe.StringData(clone))
}
Output:
true
false
func Compare
func Compare(a, b string) int
Compare возвращает целое число, сравнивающее две строки лексикографически. Результат будет 0, если a == b, -1, если a < b, и +1, если a > b.
Используйте Compare, когда вам нужно выполнить трехстороннее сравнение (например, с помощью slices.SortFunc). Обычно более понятно и всегда быстрее использовать встроенные операторы сравнения строк ==, <, > и т. д.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Compare("a", "b"))
fmt.Println(strings.Compare("a", "a"))
fmt.Println(strings.Compare("b", "a"))
}
Output:
-1
0
1
func Contains
func Contains(s, substr string) bool
Contains сообщает, находится ли substr в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Contains("seafood", "foo"))
fmt.Println(strings.Contains("seafood", "bar"))
fmt.Println(strings.Contains("seafood", ""))
fmt.Println(strings.Contains("", ""))
}
Output:
true
false
true
true
func ContainsAny
func ContainsAny(s, chars string) bool
ContainsAny сообщает, находятся ли какие-либо кодовые точки Unicode в chars в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ContainsAny("team", "i"))
fmt.Println(strings.ContainsAny("fail", "ui"))
fmt.Println(strings.ContainsAny("ure", "ui"))
fmt.Println(strings.ContainsAny("failure", "ui"))
fmt.Println(strings.ContainsAny("foo", ""))
fmt.Println(strings.ContainsAny("", ""))
}
Output:
false
true
true
true
false
false
func ContainsFunc
func ContainsFunc(s string, f func(rune) bool) bool
ContainsFunc сообщает, удовлетворяют ли какие-либо кодовые точки Unicode r в s условию f(r).
Пример
package main
import (
"fmt"
"strings"
)
func main() {
f := func(r rune) bool {
return r == 'a' || r == 'e' || r == 'i' || r == 'o' || r == 'u'
}
fmt.Println(strings.ContainsFunc("hello", f))
fmt.Println(strings.ContainsFunc("rhythms", f))
}
Output:
true
false
func ContainsRune
func ContainsRune(s string, r rune) bool
ContainsRune сообщает, находится ли кодовая точка Unicode r в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
// Finds whether a string contains a particular Unicode code point.
// The code point for the lowercase letter "a", for example, is 97.
fmt.Println(strings.ContainsRune("aardvark", 97))
fmt.Println(strings.ContainsRune("timeout", 97))
}
Output:
true
false
func Count
func Count(s, substr string) int
Count подсчитывает количество непересекающихся вхождений substr в s. Если substr является пустой строкой, Count возвращает 1 + количество кодовых точек Unicode в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Count("cheese", "e"))
fmt.Println(strings.Count("five", "")) // before & after each rune
}
Output:
3
5
func Cut
func Cut(s, sep string) (before, after string, found bool)
Cut разрезает s вокруг первого вхождения sep, возвращая текст до и после sep. Результат found сообщает, встречается ли sep в s. Если sep не встречается в s, cut возвращает s, «», false.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
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("Gopher", "Go")
show("Gopher", "ph")
show("Gopher", "er")
show("Gopher", "Badger")
}
Output:
Cut("Gopher", "Go") = "", "pher", true
Cut("Gopher", "ph") = "Go", "er", true
Cut("Gopher", "er") = "Goph", "", true
Cut("Gopher", "Badger") = "Gopher", "", false
func CutPrefix
func CutPrefix(s, prefix string) (after string, found bool)
CutPrefix возвращает s без указанной начальной префиксной строки и сообщает, был ли найден префикс. Если s не начинается с prefix, CutPrefix возвращает s, false. Если prefix является пустой строкой, CutPrefix возвращает s, true.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
show := func(s, sep string) {
after, found := strings.CutPrefix(s, sep)
fmt.Printf("CutPrefix(%q, %q) = %q, %v\n", s, sep, after, found)
}
show("Gopher", "Go")
show("Gopher", "ph")
}
Output:
CutPrefix("Gopher", "Go") = "pher", true
CutPrefix("Gopher", "ph") = "Gopher", false
func CutSuffix
func CutSuffix(s, suffix string) (before string, found bool)
CutSuffix возвращает s без указанной конечной строки суффикса и сообщает, был ли найден суффикс. Если s не заканчивается суффиксом, CutSuffix возвращает s, false. Если суффикс является пустой строкой, CutSuffix возвращает s, true.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
show := func(s, sep string) {
before, found := strings.CutSuffix(s, sep)
fmt.Printf("CutSuffix(%q, %q) = %q, %v\n", s, sep, before, found)
}
show("Gopher", "Go")
show("Gopher", "er")
}
Output:
CutSuffix("Gopher", "Go") = "Gopher", false
CutSuffix("Gopher", "er") = "Goph", true
func EqualFold
func EqualFold(s, t string) bool
EqualFold сообщает, равны ли s и t, интерпретируемые как строки UTF-8, при простом преобразовании регистра Unicode, которое является более общей формой нечувствительности к регистру.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.EqualFold("Go", "go"))
fmt.Println(strings.EqualFold("AB", "ab")) // true because comparison uses simple case-folding
fmt.Println(strings.EqualFold("ß", "ss")) // false because comparison does not use full case-folding
}
Output:
true
true
false
func Fields
func Fields(s string) []string
Fields разбивает строку s по каждому вхождению одного или нескольких последовательных пробелов, как определено в unicode.IsSpace, возвращая массив подстрок s или пустой массив, если s содержит только пробелы.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz "))
}
Output:
Fields are: ["foo" "bar" "baz"]
func FieldsFunc
func FieldsFunc(s string, f func(rune) bool) []string
FieldsFunc разбивает строку s на каждом проходе кодовых точек Unicode c, удовлетворяющих f(c), и возвращает массив фрагментов s. Если все кодовые точки в s удовлетворяют f(c) или строка пуста, возвращается пустой фрагмент.
FieldsFunc не дает никаких гарантий относительно порядка вызова f(c) и предполагает, что f всегда возвращает одно и то же значение для данного c.
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
f := func(c rune) bool {
return !unicode.IsLetter(c) && !unicode.IsNumber(c)
}
fmt.Printf("Fields are: %q", strings.FieldsFunc(" foo1;bar2,baz3...", f))
}
Output:
Fields are: ["foo1" "bar2" "baz3"]
func FieldsFuncSeq
func FieldsFuncSeq(s string, f func(rune) bool) iter.Seq[string]
FieldsFuncSeq возвращает итератор над подстроками s, разбитыми по последовательностям кодовых точек Unicode, удовлетворяющих f(c). Итератор возвращает те же строки, что и FieldsFunc(s), но без построения среза.
func FieldsSeq
func FieldsSeq(s string) iter.Seq[string]
FieldsSeq возвращает итератор над подстроками s, разбитыми по последовательностям пробельных символов, как определено в unicode.IsSpace. Итератор возвращает те же строки, что и Fields(s), но без построения среза.
func HasPrefix
func HasPrefix(s, prefix string) bool
HasPrefix сообщает, начинается ли строка s с префикса.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.HasPrefix("Gopher", "Go"))
fmt.Println(strings.HasPrefix("Gopher", "C"))
fmt.Println(strings.HasPrefix("Gopher", ""))
}
Output:
true
false
true
func HasSuffix
func HasSuffix(s, suffix string) bool
HasSuffix сообщает, заканчивается ли строка s суффиксом.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.HasSuffix("Amigo", "go"))
fmt.Println(strings.HasSuffix("Amigo", "O"))
fmt.Println(strings.HasSuffix("Amigo", "Ami"))
fmt.Println(strings.HasSuffix("Amigo", ""))
}
Output:
true
false
false
true
func Index
func Index(s, substr string) int
Index возвращает индекс первого вхождения substr в s или -1, если substr отсутствует в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Index("chicken", "ken"))
fmt.Println(strings.Index("chicken", "dmr"))
}
Output:
4
-1
func IndexAny
func IndexAny(s, chars string) int
IndexAny возвращает индекс первого вхождения любого кодового пункта Unicode из chars в s, или -1, если ни один кодовый пункт Unicode из chars не присутствует в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.IndexAny("chicken", "aeiouy"))
fmt.Println(strings.IndexAny("crwth", "aeiouy"))
}
Output:
2
-1
func IndexByte
func IndexByte(s string, c byte) int
IndexByte возвращает индекс первого вхождения c в s, или -1, если c отсутствует в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.IndexByte("golang", 'g'))
fmt.Println(strings.IndexByte("gophers", 'h'))
fmt.Println(strings.IndexByte("golang", 'x'))
}
Output:
0
3
-1
func IndexFunc
func IndexFunc(s string, f func(rune) bool) int
IndexFunc возвращает индекс в s первого кодового пункта Unicode, удовлетворяющего f(c), или -1, если такового нет.
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
f := func(c rune) bool {
return unicode.Is(unicode.Han, c)
}
fmt.Println(strings.IndexFunc("Hello, 世界", f))
fmt.Println(strings.IndexFunc("Hello, world", f))
}
Output:
7
-1
func IndexRune
func IndexRune(s string, r rune) int
IndexRune возвращает индекс первого вхождения кодовой точки Unicode r, или -1, если rune отсутствует в s. Если r является utf8.RuneError, то возвращается первое вхождение любой недопустимой последовательности байтов UTF-8.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.IndexRune("chicken", 'k'))
fmt.Println(strings.IndexRune("chicken", 'd'))
}
Output:
4
-1
func Join
func Join(elems []string, sep string) string
Join объединяет элементы своего первого аргумента, создавая одну строку. Разделитель sep помещается между элементами в результирующей строке.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
s := []string{"foo", "bar", "baz"}
fmt.Println(strings.Join(s, ", "))
}
Output:
foo, bar, baz
func LastIndex
func LastIndex(s, substr string) int
LastIndex возвращает индекс последнего вхождения substr в s, или -1, если substr отсутствует в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Index("go gopher", "go"))
fmt.Println(strings.LastIndex("go gopher", "go"))
fmt.Println(strings.LastIndex("go gopher", "rodent"))
}
Output:
0
3
-1
func LastIndexAny
func LastIndexAny(s, chars string) int
LastIndexAny возвращает индекс последнего вхождения любого кодового пункта Unicode из chars в s, или -1, если в s нет кодовых пунктов Unicode из chars.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.LastIndexAny("go gopher", "go"))
fmt.Println(strings.LastIndexAny("go gopher", "rodent"))
fmt.Println(strings.LastIndexAny("go gopher", "fail"))
}
Output:
4
8
-1
func LastIndexByte
func LastIndexByte(s string, c byte) int
LastIndexByte возвращает индекс последнего вхождения c в s, или -1, если c отсутствует в s.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.LastIndexByte("Hello, world", 'l'))
fmt.Println(strings.LastIndexByte("Hello, world", 'o'))
fmt.Println(strings.LastIndexByte("Hello, world", 'x'))
}
Output:
10
8
-1
func LastIndexFunc
func LastIndexFunc(s string, f func(rune) bool) int
LastIndexFunc возвращает индекс в s последней кодовой точки Unicode, удовлетворяющей f(c), или -1, если таковой нет.
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Println(strings.LastIndexFunc("go 123", unicode.IsNumber))
fmt.Println(strings.LastIndexFunc("123 go", unicode.IsNumber))
fmt.Println(strings.LastIndexFunc("go", unicode.IsNumber))
}
Output:
5
2
-1
func Lines
func Lines(s string) iter.Seq[string]
Lines возвращает итератор по строкам, отделенным символом новой строки, в строке s. Строки, возвращаемые итератором, включают в себя символы новой строки, отделяющие их. Если s пуста, итератор не возвращает никаких строк. Если s не заканчивается символом новой строки, последняя возвращаемая строка не будет заканчиваться символом новой строки. Возвращает итератор однократного использования.
func Map
func Map(mapping func(rune) rune, s string) string
Map возвращает копию строки s со всеми ее символами, измененными в соответствии с функцией отображения. Если отображение возвращает отрицательное значение, символ удаляется из строки без замены.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
rot13 := func(r rune) rune {
switch {
case r >= 'A' && r <= 'Z':
return 'A' + (r-'A'+13)%26
case r >= 'a' && r <= 'z':
return 'a' + (r-'a'+13)%26
}
return r
}
fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
}
Output:
'Gjnf oevyyvt naq gur fyvgul tbcure...
func Repeat
func Repeat(s string, count int) string
Repeat возвращает новую строку, состоящую из count копий строки s.
Функция выдает ошибку, если count отрицательно или если результат (len(s) * count) переполняет буфер.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println("ba" + strings.Repeat("na", 2))
}
Output:
banana
func Replace
func Replace(s, old, new string, n int) string
Replace возвращает копию строки s, в которой первые n неперекрывающихся экземпляров old заменены на new. Если old пустое, оно совпадает в начале строки и после каждой последовательности UTF-8, давая до k+1 замен для строки k-рун. Если n < 0, количество замен не ограничено.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
}
Output:
oinky oinky oink
moo moo moo
func ReplaceAll
func ReplaceAll(s, old, new string) string
ReplaceAll возвращает копию строки s со всеми неперекрывающимися вхождениями old, замененными на new. Если old пустое, оно совпадает с началом строки и после каждой последовательности UTF-8, давая до k+1 замен для строки из k рун.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ReplaceAll("oink oink oink", "oink", "moo"))
}
Output:
moo moo moo
func Split
func Split(s, sep string) []string
Split разделяет s на все подстроки, разделенные sep, и возвращает набор подстрок между этими разделителями.
Если s не содержит sep, а sep не пустой, Split возвращает набор длиной 1, единственным элементом которого является s.
Если sep пустой, Split разделяет после каждой последовательности UTF-8. Если и s, и sep пустые, Split возвращает пустой набор.
Это эквивалентно SplitN с количеством -1.
Чтобы разделить вокруг первого вхождения разделителя, см. Cut.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%q\n", strings.Split("a,b,c", ","))
fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
fmt.Printf("%q\n", strings.Split(" xyz ", ""))
fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))
}
Output:
["a" "b" "c"]
["" "man " "plan " "canal panama"]
[" " "x" "y" "z" " "]
[""]
func SplitAfter
func SplitAfter(s, sep string) []string
SplitAfter разделяет s на все подстроки после каждого вхождения sep и возвращает срез этих подстрок.
Если s не содержит sep, а sep не пустой, SplitAfter возвращает срез длиной 1, единственным элементом которого является s.
Если sep пусто, SplitAfter разделяет после каждой последовательности UTF-8. Если и s, и sep пусты, SplitAfter возвращает пустой срез.
Это эквивалентно SplitAfterN с количеством -1.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
}
Output:
["a," "b," "c"]
func SplitAfterN
func SplitAfterN(s, sep string, n int) []string
SplitAfterN разделяет s на подстроки после каждого вхождения sep и возвращает срез этих подстрок.
Число определяет количество подстрок, которые будут возвращены:
n > 0: не более n подстрок; последняя подстрока будет неразделенным остатком; n == 0: результат равен nil (ноль подстрок); n < 0: все подстроки. Крайние случаи для s и sep (например, пустые строки) обрабатываются, как описано в документации для SplitAfter.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))
}
Output:
["a," "b,c"]
func SplitAfterSeq
func SplitAfterSeq(s, sep string) iter.Seq[string]
SplitAfterSeq возвращает итератор над подстроками s, разделенными после каждого вхождения sep. Итератор возвращает те же строки, которые были бы возвращены SplitAfter(s, sep), но без построения слайса. Он возвращает итератор однократного использования.
func SplitN
func SplitN(s, sep string, n int) []string
SplitN разделяет s на подстроки, разделенные sep, и возвращает срез подстрок между этими разделителями.
Число определяет количество подстрок, которые будут возвращены:
n > 0: не более n подстрок; последняя подстрока будет неразделенной остаточной частью; n == 0: результат равен nil (ноль подстрок); n < 0: все подстроки. Крайние случаи для s и sep (например, пустые строки) обрабатываются, как описано в документации по Split.
Чтобы разделить вокруг первого вхождения разделителя, см. Cut.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2))
z := strings.SplitN("a,b,c", ",", 0)
fmt.Printf("%q (nil = %v)\n", z, z == nil)
}
Output:
["a" "b,c"]
[] (nil = true)
func SplitSeq
func SplitSeq(s, sep string) iter.Seq[string]
SplitSeq возвращает итератор по всем подстрокам s, разделенным sep. Итератор возвращает те же строки, что и Split(s, sep), но без создания слайса. Он возвращает итератор однократного использования.
func Title (устарело)
func ToLower
func ToLower(s string) string
ToLower возвращает s со всеми буквами Unicode, преобразованными в нижний регистр.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToLower("Gopher"))
}
Output:
gopher
func ToLowerSpecial
func ToLowerSpecial(c unicode.SpecialCase, s string) string
ToLowerSpecial возвращает копию строки s со всеми буквами Unicode, преобразованными в нижний регистр с использованием преобразования регистра, указанного c.
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Println(strings.ToLowerSpecial(unicode.TurkishCase, "Örnek İş"))
}
Output:
örnek iş
func ToTitle
func ToTitle(s string) string
ToTitle возвращает копию строки s, в которой все буквы Unicode преобразованы в заглавные.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
// Compare this example to the Title example.
fmt.Println(strings.ToTitle("her royal highness"))
fmt.Println(strings.ToTitle("loud noises"))
fmt.Println(strings.ToTitle("брат"))
}
HER ROYAL HIGHNESS
LOUD NOISES
БРАТ
func ToTitleSpecial
func ToTitleSpecial(c unicode.SpecialCase, s string) string
ToTitleSpecial возвращает копию строки s, в которой все буквы Unicode преобразованы в заглавные, с приоритетом специальных правил преобразования регистра.
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Println(strings.ToTitleSpecial(unicode.TurkishCase, "dünyanın ilk borsa yapısı Aizonai kabul edilir"))
}
Output:
DÜNYANIN İLK BORSA YAPISI AİZONAİ KABUL EDİLİR
func ToUpper
func ToUpper(s string) string
ToUpper возвращает s, в которой все буквы Unicode преобразованы в заглавные.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToUpper("Gopher"))
}
Output:
GOPHER
func ToUpperSpecial
func ToUpperSpecial(c unicode.SpecialCase, s string) string
ToUpperSpecial возвращает копию строки s, в которой все буквы Unicode преобразованы в верхний регистр с использованием преобразования регистра, указанного в c.
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Println(strings.ToUpperSpecial(unicode.TurkishCase, "örnek iş"))
}
Output:
ÖRNEK İŞ
func ToValidUTF8
func ToValidUTF8(s, replacement string) string
ToValidUTF8 возвращает копию строки s, в которой каждая последовательность недопустимых байтов UTF-8 заменена строкой replacement, которая может быть пустой.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%s\n", strings.ToValidUTF8("abc", "\uFFFD"))
fmt.Printf("%s\n", strings.ToValidUTF8("a\xffb\xC0\xAFc\xff", ""))
fmt.Printf("%s\n", strings.ToValidUTF8("\xed\xa0\x80", "abc"))
}
Output:
abc
abc
abc
func Trim
func Trim(s, cutset string) string
Trim возвращает фрагмент строки s, из которого удалены все начальные и конечные кодовые точки Unicode, содержащиеся в cutset.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Print(strings.Trim("¡¡¡Hello, Gophers!!!", "!¡"))
}
Output:
Hello, Gophers
func TrimFunc
func TrimFunc(s string, f func(rune) bool) string
TrimFunc возвращает фрагмент строки s, из которого удалены все начальные и конечные кодовые точки Unicode c, удовлетворяющие f(c).
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Print(strings.TrimFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
}))
}
Output:
Hello, Gophers
func TrimLeft
func TrimLeft(s, cutset string) string
TrimLeft возвращает фрагмент строки s, из которого удалены все начальные кодовые точки Unicode, содержащиеся в cutset.
Чтобы удалить префикс, используйте вместо этого TrimPrefix.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Print(strings.TrimLeft("¡¡¡Hello, Gophers!!!", "!¡"))
}
Output:
Hello, Gophers!!!
func TrimLeftFunc
func TrimLeftFunc(s string, f func(rune) bool) string
TrimLeftFunc возвращает фрагмент строки s, из которого удалены все начальные кодовые точки Unicode c, удовлетворяющие f(c).
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Print(strings.TrimLeftFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
}))
}
Output:
Hello, Gophers!!!
func TrimPrefix
func TrimPrefix(s, prefix string) string
TrimPrefix возвращает s без указанного начального префикса string. Если s не начинается с префикса, s возвращается без изменений.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
var s = "¡¡¡Hello, Gophers!!!"
s = strings.TrimPrefix(s, "¡¡¡Hello, ")
s = strings.TrimPrefix(s, "¡¡¡Howdy, ")
fmt.Print(s)
}
Output:
Gophers!!!
func TrimRight
func TrimRight(s, cutset string) string
TrimRight возвращает фрагмент строки s, из которого удалены все конечные кодовые точки Unicode, содержащиеся в cutset.
Чтобы удалить суффикс, используйте вместо этого TrimSuffix.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Print(strings.TrimRight("¡¡¡Hello, Gophers!!!", "!¡"))
}
Output:
¡¡¡Hello, Gophers
func TrimRightFunc
func TrimRightFunc(s string, f func(rune) bool) string
TrimRightFunc возвращает фрагмент строки s, из которого удалены все конечные кодовые точки Unicode c, удовлетворяющие f(c).
Пример
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Print(strings.TrimRightFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
}))
}
Output:
¡¡¡Hello, Gophers
func TrimSpace
func TrimSpace(s string) string
TrimSpace возвращает фрагмент строки s, из которого удалены все ведущие и конечные пробелы, как определено в Unicode.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.TrimSpace(" \t\n Hello, Gophers \n\t\r\n"))
}
Output:
Hello, Gophers
func TrimSuffixy
func TrimSuffix(s, suffix string) string
TrimSuffix возвращает s без указанного конечного суффикса string. Если s не заканчивается суффиксом, s возвращается без изменений.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
var s = "¡¡¡Hello, Gophers!!!"
s = strings.TrimSuffix(s, ", Gophers!!!")
s = strings.TrimSuffix(s, ", Marmots!!!")
fmt.Print(s)
}
Output:
¡¡¡Hello
2 - Описание типов пакета string языка программирования Go
type Builder
type Builder struct {
// содержит отфильтрованные или неэкспортируемые поля
}
Builder используется для эффективного построения строки с помощью методов Builder.Write. Он минимизирует копирование памяти. Нулевое значение готово к использованию. Не копируйте Builder, отличное от нуля.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
for i := 3; i >= 1; i-- {
fmt.Fprintf(&b, "%d...", i)
}
b.WriteString("ignition")
fmt.Println(b.String())
}
Output:
3...2...1...ignition
Объяснение Builder
Builder
из пакета strings
- это специальный тип для эффективного построения строк в Go. Он особенно полезен, когда вам нужно собрать строку из множества частей, так как он минимизирует копирование памяти и аллокации.
Основные преимущества Builder:
- Эффективность памяти - избегает лишних копирований данных
- Простота использования - предоставляет удобные методы для добавления содержимого
- Готовность к использованию - нулевое значение (
var b strings.Builder
) сразу готово к работе
Основные методы:
Write()
- добавляет байтыWriteString()
- добавляет строкуWriteByte()
- добавляет один байтWriteRune()
- добавляет руну (Unicode символ)String()
- возвращает собранную строкуReset()
- очищает builder для повторного использованияLen()
- возвращает текущую длинуCap()
- возвращает текущую емкостьGrow()
- заранее резервирует память
Примеры использования:
1. Базовый пример
package main
import (
"fmt"
"strings"
)
func main() {
var builder strings.Builder
builder.WriteString("Hello, ")
builder.WriteString("World!")
builder.WriteByte(' ')
builder.WriteRune('😊')
result := builder.String()
fmt.Println(result) // Hello, World! 😊
}
2. Эффективная конкатенация множества строк
func joinStrings(words []string) string {
var builder strings.Builder
// Заранее выделяем память для приблизительного размера
total := 0
for _, w := range words {
total += len(w)
}
builder.Grow(total)
for _, word := range words {
builder.WriteString(word)
}
return builder.String()
}
3. Построение JSON или HTML
func buildHTMLPage(title, body string) string {
var builder strings.Builder
builder.Grow(len(title) + len(body) + 50) // Примерный расчет
builder.WriteString("<html><head><title>")
builder.WriteString(title)
builder.WriteString("</title></head><body>")
builder.WriteString(body)
builder.WriteString("</body></html>")
return builder.String()
}
4. Повторное использование Builder
var builder strings.Builder
func logMessage(msg string) string {
builder.Reset() // Очищаем для повторного использования
builder.WriteString("[LOG] ")
builder.WriteString(time.Now().Format("2006-01-02 15:04:05"))
builder.WriteString(": ")
builder.WriteString(msg)
return builder.String()
}
Почему Builder лучше обычной конкатенации?
При обычной конкатенации строк с помощью +
:
s := "a" + "b" + "c" + "d"
Каждая операция создает новую строку, что приводит к лишним аллокациям памяти.
Builder же:
- Накапливает данные в буфере
- Увеличивает буфер только когда нужно
- Копирует данные минимальное количество раз
Когда использовать strings.Builder?
- Когда нужно собрать строку из многих частей
- Когда важна производительность (особенно в циклах)
- Когда заранее известен приблизительный размер результата (можно использовать Grow)
- Когда нужно минимизировать аллокации памяти
Builder особенно полезен в высоконагруженных участках кода, где важна эффективность работы со строками.
func (*Builder) Cap
func (b *Builder) Cap() int
Cap возвращает емкость базового байтового слайса builder. Это общее пространство, выделенное для строчки, которая создается, и включает в себя все уже записанные байты.
func (*Builder) Grow
func (b *Builder) Grow(n int)
Grow увеличивает емкость b, если это необходимо, чтобы гарантировать пространство для еще n байтов. После Grow(n) в b можно записать как минимум n байтов без дополнительного выделения памяти. Если n отрицательно, Grow вызывает панику.
func (*Builder) Len
func (b *Builder) Len() int
Len возвращает количество накопленных байтов; b.Len() == len(b.String()).
func (*Builder) Reset
func (b *Builder) Reset()
Reset сбрасывает Builder в пустое состояние.
func (*Builder) String
func (b *Builder) String() string
String возвращает накопленную строку.
func (*Builder) Write
func (b *Builder) Write(p []byte) (int, error)
Write добавляет содержимое p в буфер b. Write всегда возвращает len(p), nil.
func (*Builder) WriteByte
func (b *Builder) WriteByte(c byte) error
WriteByte добавляет байт c в буфер b. Возвращаемая ошибка всегда равна nil.
func (*Builder) WriteRune
func (b *Builder) WriteRune(r rune) (int, error)
WriteRune добавляет UTF-8-кодировку кодовой точки Unicode r в буфер b. Возвращает длину r и ошибку nil.
func (*Builder) WriteString
func (b *Builder) WriteString(s string) (int, error)
WriteString добавляет содержимое s в буфер b. Возвращает длину s и ошибку nil.
type Reader
type Reader struct {
// содержит отфильтрованные или неэкспортируемые поля
}
Reader реализует интерфейсы io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.RuneReader, io.RuneScanner, io.Seeker и io.WriterTo, читая из строки. Нулевое значение для Reader работает как Reader пустой строки.
Объяснение Reader
Reader
из пакета strings
- это тип, который реализует множество интерфейсов для чтения из строки как из потока данных. Это мощный инструмент, когда вам нужно работать со строкой как с последовательностью байт или рун, поддерживающий различные операции чтения и навигации.
Основные особенности Reader:
- Чтение строки как потока - позволяет обрабатывать строку постепенно
- Реализация множества интерфейсов - совместим со стандартными интерфейсами ввода-вывода Go
- Поддержка позиционирования - можно перемещаться по строке
- Нулевое значение готово к работе -
var r strings.Reader
работает с пустой строкой
Реализуемые интерфейсы:
io.Reader
- базовое чтение байтовio.ReaderAt
- чтение с определенной позицииio.ByteReader
- чтение отдельных байтовio.ByteScanner
- чтение и возврат байтовio.RuneReader
- чтение рун (Unicode символов)io.RuneScanner
- чтение и возврат рунio.Seeker
- перемещение по строкеio.WriterTo
- запись содержимого в io.Writer
Основные методы:
Len() int
- количество непрочитанных байтовRead(b []byte) (n int, err error)
- чтение байтов в срезReadAt(b []byte, off int64) (n int, err error)
- чтение с определенной позицииReadByte() (byte, error)
- чтение одного байтаUnreadByte() error
- возврат последнего прочитанного байтаReadRune() (ch rune, size int, err error)
- чтение одной руныUnreadRune() error
- возврат последней прочитанной руныSeek(offset int64, whence int) (int64, error)
- перемещение по строкеWriteTo(w io.Writer) (n int64, err error)
- запись всего содержимого в WriterReset(s string)
- сброс Reader для чтения новой строки
Примеры использования:
1. Базовое чтение
package main
import (
"fmt"
"strings"
)
func main() {
r := strings.NewReader("Пример строки")
buf := make([]byte, 7)
n, err := r.Read(buf)
fmt.Printf("Прочитано %d байт: %q\n", n, buf[:n])
// Прочитано 7 байт: "Пример"
}
2. Чтение рун
func printRunes(s string) {
r := strings.NewReader(s)
for {
ch, size, err := r.ReadRune()
if err != nil {
break
}
fmt.Printf("%c (%d байт)\n", ch, size)
}
}
// Для строки "Привет" выведет:
// П (2 байт)
// р (2 байт)
// и (2 байт)
// в (2 байт)
// е (2 байт)
// т (2 байт)
3. Использование Seek для навигации
func seekExample() {
r := strings.NewReader("Hello, World!")
// Пропускаем "Hello, "
r.Seek(7, io.SeekStart)
b, _ := r.ReadByte()
fmt.Printf("Первый байт после Seek: %c\n", b) // W
}
4. Чтение с определенной позиции (ReadAt)
func readAtExample() {
r := strings.NewReader("abcdefghij")
buf := make([]byte, 3)
r.ReadAt(buf, 4)
fmt.Println(string(buf)) // efg
}
5. Запись содержимого в другой Writer
func writeToExample(w io.Writer) {
r := strings.NewReader("Данные для записи")
r.WriteTo(w) // Запишет всю строку в w
}
6. Комбинирование методов
func processString(s string) {
r := strings.NewReader(s)
// Читаем первые 5 байт
prefix := make([]byte, 5)
r.Read(prefix)
// Читаем оставшуюся часть по рунам
for {
ch, _, err := r.ReadRune()
if err != nil {
break
}
// Обработка руны...
}
}
Когда использовать strings.Reader?
- Когда нужно читать строку по частям - как из потока
- Для совместимости с API, ожидающими io.Reader - многие функции принимают io.Reader
- Когда нужен произвольный доступ к частям строки - через ReadAt/Seek
- Для обработки Unicode текста - через ReadRune
- Когда нужно повторно “проиграть” часть данных - через UnreadByte/UnreadRune
Преимущества перед работой со строкой напрямую:
- Постепенная обработка - не нужно загружать всю строку в память
- Стандартные интерфейсы - совместимость с другими пакетами
- Гибкость навигации - возможность перемещаться по строке
- Безопасность - Reader неизменяем, исходная строка защищена от модификаций
Reader особенно полезен при парсинге, обработке больших строк или когда вам нужно интегрировать строку в систему, работающую с потоками данных.
func NewReader
func NewReader(s string) *Reader
NewReader возвращает новый Reader, читающий из s. Он похож на bytes.NewBufferString, но более эффективен и не поддается записи.
func (*Reader) Len
func (r *Reader) Len() int
Len возвращает количество байтов непрочитанной части строки.
func (*Reader) Read
func (r *Reader) Read(b []byte) (n int, err error)
Read реализует интерфейс io.Reader.
func (*Reader) ReadAt
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)
ReadAt реализует интерфейс io.ReaderAt.
func (*Reader) ReadByte
func (r *Reader) ReadByte() (byte, error)
ReadByte реализует интерфейс io.ByteReader.
func (*Reader) ReadRune
func (r *Reader) ReadRune() (ch rune, size int, err error)
ReadRune реализует интерфейс io.RuneReader.
func (*Reader) Reset
func (r *Reader) Reset(s string)
Reset сбрасывает Reader для чтения из s.
func (*Reader) Seek
func (r *Reader) Seek(offset int64, whence int) (int64, error)
Seek реализует интерфейс io.Seeker.
func (*Reader) Size
func (r *Reader) Size() int64
Size возвращает исходную длину базовой строки. Size — это количество байтов, доступных для чтения с помощью Reader.ReadAt. Возвращаемое значение всегда одинаково и не зависит от вызовов других методов.
func (*Reader) UnreadByte
func (r *Reader) UnreadByte() error
UnreadByte реализует интерфейс io.ByteScanner.
func (*Reader) UnreadRune
func (r *Reader) UnreadRune() error
UnreadRune реализует интерфейс io.RuneScanner.
func (*Reader) WriteTo
func (r *Reader) WriteTo(w io.Writer) (n int64, err error)
WriteTo реализует интерфейс io.WriterTo.
type Replacer
type Replacer struct {
// содержит отфильтрованные или неэкспортируемые поля
}
Replacer заменяет список строк на замены. Он безопасен для одновременного использования несколькими goroutines.
Объяснение Replacer
Replacer
- это мощный инструмент для замены подстрок в Go, который оптимизирован для многократного использования и безопасен для конкурентного использования в горутинах.
Основные характеристики
- Горутин-безопасность: Можно использовать из нескольких горутин одновременно
- Оптимизированная производительность: Быстрее, чем последовательные вызовы
strings.Replace()
- Поддержка множественных замен: Может обрабатывать множество замен за один проход по строке
- Кэширование: Сохраняет оптимизированное состояние для повторного использования
Создание Replacer
Создается с помощью strings.NewReplacer()
, который принимает пары “старая строка - новая строка”:
replacer := strings.NewReplacer(
"старое1", "новое1",
"старое2", "новое2",
// ...
)
Основные методы
Replace(input string) string
Заменяет все вхождения заданных подстрок в входной строке:
func main() {
r := strings.NewReplacer("мир", "Go", "Привет", "Здравствуй")
result := r.Replace("Привет, мир!")
fmt.Println(result) // "Здравствуй, Go!"
}
WriteString(w io.Writer, s string) (n int, err error)
Записывает строку с выполненными заменами непосредственно в io.Writer
:
func writeReplaced(w io.Writer) {
r := strings.NewReplacer("\n", "\\n", "\t", "\\t")
r.WriteString(w, "Строка с\nпереносами\tи табуляцией")
// Запишет: "Строка с\nпереносами\tи табуляцией"
}
Примеры использования
1. Экранирование специальных символов
func escapeHTML(s string) string {
replacer := strings.NewReplacer(
"&", "&",
"<", "<",
">", ">",
"\"", """,
)
return replacer.Replace(s)
}
2. Транслитерация
func transliterate(s string) string {
return strings.NewReplacer(
"щ", "shh", "ш", "sh", "ч", "ch",
"я", "ya", "ю", "yu", "ж", "zh",
).Replace(s)
}
3. Множественные замены в большом тексте
func processText(text string) string {
replacer := strings.NewReplacer(
"красный", "синий",
"яблоко", "апельсин",
"собака", "кошка",
)
return replacer.Replace(text)
}
4. Обработка логов
func cleanLog(log string) string {
return strings.NewReplacer(
"\n", " | ",
"\t", " ",
"\r", "",
).Replace(log)
}
Особенности производительности
- Однопроходная обработка: Все замены выполняются за один проход по строке
- Оптимизация для повторного использования: Созданный
Replacer
кэширует свои внутренние структуры - Эффективность для большого числа замен: Лучше использовать один
Replacer
со многими заменами, чем несколько вызововReplace
Рекомендации по использованию
- Для многократного использования: Создавайте
Replacer
один раз и используйте многократно - Для большого числа замен: Когда нужно сделать более 2-3 замен в одной строке
- В конкурентной среде: Когда замены могут выполняться из нескольких горутин
- Для записи в Writer: Когда нужно сразу записывать результат в выходной поток
Сравнение с другими методами замены
Метод | Многопоточность | Множественные замены | Производительность | Повторное использование |
---|---|---|---|---|
strings.Replace() |
Нет | Нет (одна замена) | Средняя | Нет |
regexp.Regexp.ReplaceAllString() |
Да (с sync) | Да | Низкая (для простых замен) | Да |
strings.Replacer |
Да | Да | Высокая | Да |
Replacer
особенно полезен в веб-серверах, обработчиках запросов и других высоконагруженных приложениях, где требуется выполнять одни и те же замены многократно.
func NewReplacer
func NewReplacer(oldnew ...string) *Replacer
NewReplacer возвращает новый Replacer из списка пар старых и новых строк. Замены выполняются в том порядке, в котором они появляются в целевой строке, без перекрывающихся совпадений. Сравнение старых строк выполняется в порядке аргументов.
NewReplacer вызывает панику, если ему передано нечетное количество аргументов.
Пример
package main
import (
"fmt"
"strings"
)
func main() {
r := strings.NewReplacer("<", "<", ">", ">")
fmt.Println(r.Replace("This is <b>HTML</b>!"))
}
Output:
This is <b>HTML</b>!
func (*Replacer) Replace
func (r *Replacer) Replace(s string) string
Replace возвращает копию s со всеми выполненными заменами.
func (*Replacer) WriteString
func (r *Replacer) WriteString(w io.Writer, s string) (n int, err error)
WriteString записывает s в w со всеми выполненными заменами.