string
операция имеет чрезвычайно высокую частоту в программировании, тоstring
Какие есть полезные методы?
Прямые манипуляции со строками
Compare
- func Compare(a, b string) int
Сравните две строки лексикографически, обычно напрямую используя=
,>
,<
будет быстрее.
Содержит, содержит любые и содержит руны
- func Contains(s, substr string) bool
- func ContainsAny(s, chars string) bool
- func ContainsRune(s string, r rune) bool
нитьs
содержит ли онsubstr
, возвращает истину или ложь.
fmt.Println(strings.Contains("seafood", "foo")) // true
fmt.Println(strings.Contains("seafood", "bar")) // false
fmt.Println(strings.Contains("seafood", "")) // true
fmt.Println(strings.Contains("", "")) // true
ContainsAny
Используется для определения того, содержит ли подстрока символ в исходной строке.s
середина. подстрока пуста, возвратfalse
.
fmt.Println(strings.ContainsAny("team", "i")) // false
fmt.Println(strings.ContainsAny("fail", "ui")) // true
fmt.Println(strings.ContainsAny("ure", "ui")) // true
fmt.Println(strings.ContainsAny("failure", "ui")) // true
fmt.Println(strings.ContainsAny("foo", "")) // false
fmt.Println(strings.ContainsAny("", "")) // false
ContainsRune
Используется для определения того, присутствует ли символ, представленный кодом Ascall, в исходной строке.s
середина.
// 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))
Count
- func Count(s, substr string) int
Определить количество подстрок в исходной строке.Если подстрока пуста, длина равна длине исходной строки + 1.
fmt.Println(strings.Count("cheese", "e")) // 3
fmt.Println(strings.Count("five", "")) // before & after each rune 5=4+1
EqualFold
- func EqualFold(s, t string) bool
Определяет, являются ли две строки одинаковыми без учета регистра.
Fields
- func Fields(s string) []string
- func FieldsFunc(s string, f func(rune) bool) []string
Fields
: Используйте пробел, чтобы разделить строку.FieldsFunc
: Разделить строку в соответствии с переданной функцией, если текущий параметрc
Не цифра и не буква, возвратtrue
как разделитель.
fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz ")) // ["foo" "bar" "baz"]
f := func(c rune) bool {
return !unicode.IsLetter(c) && !unicode.IsNumber(c)
}
fmt.Printf("Fields are: %q", strings.FieldsFunc(" foo1;bar2,baz3...", f)) // ["foo1" "bar2" "baz3"]
HasPrefix и HasSuffix
- func HasPrefix(s, prefix string) bool
- func HasSuffix(s, suffix string) bool
Определяет, начинается или заканчивается строка подстрокой.
fmt.Println(strings.HasPrefix("Gopher", "Go")) // true
fmt.Println(strings.HasPrefix("Gopher", "C")) // false
fmt.Println(strings.HasPrefix("Gopher", "")) // true
fmt.Println(strings.HasSuffix("Amigo", "go")) // true
fmt.Println(strings.HasSuffix("Amigo", "O")) // false
fmt.Println(strings.HasSuffix("Amigo", "Ami")) // false
fmt.Println(strings.HasSuffix("Amigo", "")) // true
Join
- func Join(elems []string, sep string) string
использоватьsep
, строка подключения.
s := []string{"foo", "bar", "baz"}
fmt.Println(strings.Join(s, ", ")) // foo,bar,baz
Индекс, IndexAny, IndexByte, IndexFunc, IndexRune
- func Index(s, substr string) int
- func IndexAny(s, chars string) int
- func IndexByte(s string, c byte) int
- func IndexFunc(s string, f func(rune) bool) int
- func IndexRune(s string, r rune) int
Index
,IndexAny
,IndexByte
,IndexFunc
,IndexRune
Оба возвращают первую позицию, удовлетворяющую условию, если нет данных, удовлетворяющих условию, возвращают-1
.
fmt.Println(strings.Index("chicken", "ken")) // 4
fmt.Println(strings.Index("chicken", "dmr")) // -1
// 子串中的任意字符在源串出现的位置
fmt.Println(strings.IndexAny("chicken", "aeiouy")) // 2
fmt.Println(strings.IndexAny("crwth", "aeiouy")) // -1
// IndexByte,字符在字符串中出现的位置
fmt.Println(strings.IndexByte("golang", 'g')) // 0
fmt.Println(strings.IndexByte("gophers", 'h')) // 3
fmt.Println(strings.IndexByte("golang", 'x')) // -1
// IndexFunc 满足条件的作为筛选条件
f := func(c rune) bool {
return unicode.Is(unicode.Han, c)
}
fmt.Println(strings.IndexFunc("Hello, 世界", f)) // 7
fmt.Println(strings.IndexFunc("Hello, world", f)) // -1
// 某个字符在源串中的位置
fmt.Println(strings.IndexRune("chicken", 'k')) // 4
fmt.Println(strings.IndexRune("chicken", 'd')) // -1
LastIndex, LastIndexAny, LastIndexByte и LastIndexFunc
- func LastIndex(s, substr string) int
- func LastIndexAny(s, chars string) int
- func LastIndexByte(s string, c byte) int
- func LastIndexFunc(s string, f func(rune) bool) int
LastIndex
,LastIndexAny
,LastIndexByte
,LastIndexFunc
а такжеIndex
,IndexAny
,IndexByte
,IndexFunc
,IndexRune
Использование остается прежним, считая справа налево.
Map
- func Map(mapping func(rune) rune, s string) string
нанизыватьs
Каждый символ выполняет операцию в функции карты.
rot13 := func(r rune) rune { // r是遍历的每一个字符
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..."))
Repeat
- func Repeat(s string, count int) string
повторитьs
,count
Это количество повторений, и оно не может быть отрицательным.
fmt.Println("ba" + strings.Repeat("na", 2))
Заменить и заменить все
- func Replace(s, old, new string, n int) string
- func ReplaceAll(s, old, new string) string
использоватьnew
заменитьold
, число замен равноn
. еслиn
Если отрицательный, заменить все подстроки, удовлетворяющие условию.
fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2)) // oinky oinkky oink
fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1)) moo moo moo
ReplaceAll
использоватьnew
заменить всеold
, что эквивалентно использованиюReplace
Времяn<0
.
Разделить, РазделитьN, РазделитьПосле и РазделитьПослеN
- func Split(s, sep string) []string
- func SplitAfter(s, sep string) []string
- func SplitAfterN(s, sep string, n int) []string
- func SplitN(s, sep string, n int) []string
fmt.Printf("%q\n", strings.Split("a,b,c", ",")) // ["a","b","c"]
fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a ")) // ["" "man " "plan " "canal panama"]
fmt.Printf("%q\n", strings.Split(" xyz ", "")) // [" " "x" "y" "z" " "]
fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins")) // [""]
// SplitN 定义返回之后的切片中包含的长度,最后一部分是未被处理的。
fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2)) // ["a", "b,c"]
z := strings.SplitN("a,b,c", ",", 0)
fmt.Printf("%q (nil = %v)\n", z, z == nil) // [] (nil = true)
// 使用sep分割,分割出来的字符串中包含sep,可以限定分割之后返回的长度。
fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2)) // ["a,", "b,c"]
// 完全分割
fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ",")) // ["a,","b,", "c"]
заSplitN
а такжеSplitAfterN
второйn
проиллюстрировать.
n > 0: at most n substrings; the last substring will be the unsplit remainder.
n == 0: the result is nil (zero substrings)
n < 0: all substrings
Trim, TrimFunc, TrimLeft, TrimLeftFunc, TrimPrefix, TrimSuffix, TrimRight, TrimRightFunc
- func Trim(s string, cutset string) string
- func TrimFunc(s string, f func(rune) bool) string
- func TrimLeft(s string, cutset string) string
- func TrimLeftFunc(s string, f func(rune) bool) string
- func TrimPrefix(s, prefix string) string
- func TrimSuffix(s, suffix string) string
- func TrimRight(s string, cutset string) string
- func TrimRightFunc(s string, f func(rune) bool) string
// Trim 包含在cutset中的元素都会被去掉
fmt.Print(strings.Trim("¡¡¡Hello, Gophers!!!", "!¡")) // Hello, Gophers
// TrimFunc去掉满足条件的字符
fmt.Print(strings.TrimFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
}))
// TrimLeft 去掉左边满足包含在cutset中的元素,直到遇到不在cutset中的元素为止
fmt.Print(strings.TrimLeft("¡¡¡Hello, Gophers!!!", "!¡")) // Hello, Gophers!!!
// TrimLeftFunc 去掉左边属于函数返回值部分,直到遇到不在cutset中的元素为止
fmt.Print(strings.TrimLeftFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
})) // Hello, Gophers!!!
// TrimPrefix 去掉开头部分;TrimSuffix 去掉结尾部分
var s = "¡¡¡Hello, Gophers!!!"
s = strings.TrimPrefix(s, "¡¡¡Hello, ")
s = strings.TrimPrefix(s, "¡¡¡Howdy, ")
fmt.Print(s)
TrimRight
,TrimRightFunc
а такжеTrimLeft
,TrimLeftFunc
Функция осталась прежней, нет необходимости вдаваться в подробности.
Использование операций strings.Builder
A Builder is used to efficiently build a string using Write methods. It minimizes memory copying. The zero value is ready to use. Do not copy a non-zero Builder.
strings.Builder
использоватьWrite
метод для эффективного построения строк. Он минимизирует копии памяти, потребляет нулевую память и не копирует ненулевые значения.Builder
.
var b strings.Builder
for i := 3; i >= 1; i-- {
fmt.Fprintf(&b, "%d...", i)
}
b.WriteString("ignition")
fmt.Println(b.String())
Выходной результат:
3...2...1...ignition
strings.Builder
В качестве острого инструмента для сращивания струн рекомендуется использовать его более энергично.
func (b *Builder) Cap() int // 容量,涉及批量内存分配机制
func (b *Builder) Grow(n int) // 手动分配内存数量
func (b *Builder) Len() int // 当前builder中含有的所有字符长度
func (b *Builder) Reset() // 清空builder
func (b *Builder) String() string // 转化为字符串输出
func (b *Builder) Write(p []byte) (int, error) // 往builder写入数据
func (b *Builder) WriteByte(c byte) error // 往builder写入数据
func (b *Builder) WriteRune(r rune) (int, error) // 往builder写入数据
func (b *Builder) WriteString(s string) (int, error) // 往builder写入数据
использовать strings.Reader
type Reader struct {
s string //对应的字符串
i int64 // 当前读取到的位置
prevRune int
}
A Reader implements the io.Reader, io.ReaderAt, io.Seeker, io.WriterTo, io.ByteScanner, and io.RuneScanner interfaces by reading from a string. The zero value for Reader operates like a Reader of an empty string.
Reader
По чтению строки реализуется интерфейсio.Reader
, io.ReaderAt
, io.Seeker
, io.WriterTo
, io.ByteScanner
а такжеio.RuneScanner
. нулевое значениеReader
Работает как пустая строкаio.Reader
Такой же.
func NewReader(s string) *Reader // 初始化reader实例
func (r *Reader) Len() int // 未读字符长度
func (r *Reader) Read(b []byte) (n int, err error)
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)
func (r *Reader) ReadByte() (byte, error)
func (r *Reader) ReadRune() (ch rune, size int, err error)
func (r *Reader) Reset(s string) // 重置以从s中读
func (r *Reader) Seek(offset int64, whence int) (int64, error) // Seek implements the io.Seeker interface.
func (r *Reader) Size() int64 // 字符串的原始长度
func (r *Reader) UnreadByte() error
func (r *Reader) UnreadRune() error
func (r *Reader) WriteTo(w io.Writer) (n int64, err error) // WriteTo implements the io.WriterTo interface.
Лен, Размер, Чтение
Функция Len: возвращает длину непрочитанной строки.
Роль Size: возвращает длину строки.
Роль чтения: прочитать информацию о строке и изменить возвращаемое значение Len после чтения.
r := strings.NewReader("abcdefghijklmn")
fmt.Println(r.Len()) // 输出14 初始时,未读长度等于字符串长度
var buf []byte
buf = make([]byte, 5)
readLen, err := r.Read(buf)
fmt.Println("读取到的长度:", readLen) //读取到的长度5
if err != nil {
fmt.Println("错误:", err)
}
fmt.Println(buf) //adcde
fmt.Println(r.Len()) //9 读取到了5个 剩余未读是14-5
fmt.Println(r.Size()) //14 字符串的长度
ReadAt
- func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)
Прочтите оставшуюся информацию после смещения байтов в b, функция ReadAt не повлияет на значение Len.
r := strings.NewReader("abcdefghijklmn")
var bufAt, buf []byte
buf = make([]byte, 5)
r.Read(buf)
fmt.Println("剩余未读的长度", r.Len()) //剩余未读的长度 9
fmt.Println("已读取的内容", string(buf)) //已读取的内容 abcde
bufAt = make([]byte, 256)
r.ReadAt(bufAt, 5)
fmt.Println(string(bufAt)) //fghijklmn
//测试下是否影响Len和Read方法
fmt.Println("剩余未读的长度", r.Len()) //剩余未读的长度 9
fmt.Println("已读取的内容", string(buf)) //已读取的内容 abcde
ReadByte,UnreadByte
- func (r *Reader) ReadByte() (byte, error)
- func (r *Reader) UnreadByte() error
ReadByte продолжает чтение одного байта из текущей позиции чтения.
UnreadByte возвращает текущую позицию чтения на один бит и помечает байт в текущей позиции как непрочитанный байт.
ReadByte
а такжеUnreadByte
Изменит длину объекта читателя.
r := strings.NewReader("abcdefghijklmn")
//读取一个字节
b, _ := r.ReadByte()
fmt.Println(string(b)) // a
//int(r.Size()) - r.Len() 已读取字节数
fmt.Println(int(r.Size()) - r.Len()) // 1
//读取一个字节
b, _ = r.ReadByte()
fmt.Println(string(b)) // b
fmt.Println(int(r.Size()) - r.Len()) // 2
//回退一个字节
r.UnreadByte()
fmt.Println(int(r.Size()) - r.Len()) // 1
//读取一个字节
b, _ = r.ReadByte()
fmt.Println(string(b))
Seek
- func (r *Reader) Seek(offset int64, whence int) (int64, error)
ReadAt
метод не меняетсяLen()
значение ,Seek
Операцию переключения можно изменить.offset
положение смещения,whence
— начальная позиция смещения, поддерживает три позиции:io.SeekStart
стартовый бит,io.SeekCurrent
текущий бит,io.SeekEnd
Последняя позиция.offset
Это может быть отрицательное число, и значение, полученное путем добавления начального бита смещения и смещения, не может быть меньше 0 или больше длины size().
r := strings.NewReader("abcdefghijklmn")
var buf []byte
buf = make([]byte, 5)
r.Read(buf)
fmt.Println(string(buf), r.Len()) //adcde 9
buf = make([]byte, 5)
r.Seek(-2, io.SeekCurrent) //从当前位置向前偏移两位 (5-2)
r.Read(buf)
fmt.Println(string(buf), r.Len()) //defgh 6
buf = make([]byte, 5)
r.Seek(-3, io.SeekEnd) //设置当前位置是末尾前移三位
r.Read(buf)
fmt.Println(string(buf), r.Len()) //lmn 0
buf = make([]byte, 5)
r.Seek(3, io.SeekStart) //设置当前位置是起始位后移三位
r.Read(buf)
fmt.Println(string(buf), r.Len()) //defgh 6