08Go字符串詳解

Go字符串詳解

總結:正則表達式

  • 字符串是不可變值類型,內部⽤指針指向 UTF-8 字節數組。
  • 默認值是空字符串 ""。
  • ⽤索引號訪問某字節,如 s[i]。取出的是字節,不是字符
  • 不能⽤序號獲取字節元素指針, &s[i] ⾮法。
  • 不可變類型,⽆法修改字節數組。使用[]rune進行修改是從新分配內存,並複製字節數組
  • 字符串能夠用==和<進行比較;
  • go語言的字符串是utf-8的定長字符序列,會自動轉爲Unicode,而後能夠經過[]rune按索引取出字符。

一、字符串的定義

在Go語言中,字符串字面量使用雙引號 "" 或者反引號 ' 來建立。數組

  • 雙引號用來建立可解析的字符串,支持轉義,但不能用來引用多行;
  • 反引號用來建立原生的字符串字面量,可能由多行組成,但不支持轉義,而且能夠包含除了反引號外其餘全部字符。
  • 雙引號建立可解析的字符串應用最普遍,反引號用來建立原生的字符串則多用於書寫多行消息,HTML以及正則表達式。
s:="今天很開心"
s:=`今天開心嗎
    不開心啊
        真的?`

二、字符串操做

(1)字符串支持 + 鏈接操做和+=追加操做

鏈接跨⾏字符串時, "+" 必須在上⼀⾏末尾,不然致使編譯錯誤。
s := "Hello, " +
    "World!"
s2 := "Hello, "
    + "World!"   // Error: invalid operation: + untyped string

s+="abc"

其餘函數鏈接這裏暫不說明函數

(2)⽀持⽤兩個索引號返回⼦串。⼦串依然指向原字節數組,僅修改了指針和⻓度屬性。

s := "Hello, World!"
s1 := s[:5] // Hello
s2 := s[7:] // World!
s3 := s[1:5] // ello

注意:若是字符串中有漢字,漢字佔得就是3個字節,因此就不必定能取出學習

(3)字符串底層分析

struct String{//字符串是個不可變值類型, 存儲了字節和長度
    byte* str;
    intgo len;
};

字符串是 UTF-8 字符的一個序列(當字符爲 ASCII 碼時則佔用 1 個字節,其它字符根據須要佔用 2-4 個字節) 編碼

go語言中字符串的字節使用UTF-8編碼表示Unicode文本。所以Go語言字符串是變寬字符序列,每個字符都用一個或者多個字符表示,這跟其餘的(C++,Java,Python 3)的字符串類型有着本質上的不一樣,後者爲定寬字符序列。指針

每個Unicode字符都有一個惟一的叫作「碼點」的標識數字。在Go語言中,一個單一的碼點在內存中以 rune 的形式表示,rune表示int32類型的別名。能夠將Go語言的字符串轉化爲Unicode碼點切片(類型爲 [ ]rune),切片是支持直接索引的。code

package main
import(
    "fmt"
)
func main() {
    s:="abc好好學習"
    fmt.Println(s)
    for _,b:=range []byte(s){
        fmt.Printf("%x ",b) //打印16進制
    }
    fmt.Println("\n字節長度:",len(s))
    
    for i,ch:=range s{ //ch 是rune  int32別名4個字節
        fmt.Printf("(%d %x)",i,ch)
    }
    fmt.Println()
    for i,ch:=range []rune(s){
        fmt.Printf("(%d %c)",i,ch)
    }
}
//輸出結果
abc好好學習
61 62 63 e5 a5 bd e5 a5 bd e5 ad a6 e4 b9 a0 
字節長度: 15
(0 61)(1 62)(2 63)(3 597d)(6 597d)(9 5b66)(12 4e60)
(0 a)(1 b)(2 c)(3 好)(4 好)(5 學)(6 習)

上面代碼顯示,咱們把字符串轉爲[]bype數組,打印出utf-8的字節,能夠看到「學」這個漢字佔了e5 ad a6三個16進制字節。看到一個漢字佔3個字節,一個英文字母佔1個字節,utf-8是可變寬度。索引

遍歷s,取出的是Unicode碼,能夠看到「學」這個漢字的Unicode是 5b66,它是從第9個開始的,(9 5b66)。內存

將字符串轉爲[]rune 也就是int32的別名,佔4個字節。打印出了abc好好學習。utf-8

說明:go語言的字符串是utf-8的定長字符序列,會自動轉爲Unicode,而後能夠經過[]rune按索引取出字符。

三、String包的使用

查找操做
func Contains(s, substr string) bool
func Index(s, sep string) int
func Count(s, sep string) int
重複操做
func Repeat(s string, count int) string
替換操做
func Replace(s, old, new string, n int) string
刪除操做
func Trim(s string, cutset string) string
大小寫轉換
func Title(s string) string
func ToLower(s string) string
func ToUpper(s string) string
字符串前綴後綴
func HasPrefix(s, prefix string) bool
func HasSuffix(s, suffix string) bool
字符串分割
func Split(s, sep string) []string
func Fields(s string) []string

查找操做

判斷給定字符串s中是否包含子串substr, 找到返回true, 找不到返回false

func Contains(s, substr string) bool

實例以下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println("包含子串返回:", strings.Contains("oldboy", "boy"))
    fmt.Println("不包含子串返回:", strings.Contains("oldboy", "girl"))
    fmt.Println("子字符串是空字符串返回:", strings.Contains("hello", ""))
    fmt.Println("原字符串、子字符串都是空字符串返回:", strings.Contains("", ""))
    fmt.Println("中文字符串包含子串返回:", strings.Contains("我很帥", "帥"))
}

運行結果:

包含子串返回: true
不包含子串返回: false
子字符串是空字符串返回: true
原字符串、子字符串都是空字符串返回: true
中文字符串包含子串返回: true

在字符串s中查找sep所在的位置, 返回位置值, 找不到返回-1

func Index(s, sep string) int

實例以下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println("存在返回第一個匹配字符的位置:", strings.Index("heloboy", "boy"))
    fmt.Println("不存在返回:", strings.Index("helo", "day"))
    fmt.Println("中文字符串存在返回:", strings.Index("我很帥", "很帥"))
}

運行結果:

存在返回第一個匹配字符的位置: 4
不存在返回: -1
中文字符串存在返回: 3    //這裏是按照字節的順序返回 一個漢字是3個字節,因此這個是從索引爲3的開始

統計給定子串sep的出現次數, sep爲空時, 返回字符串的長度 + 1

func Count(s, sep string) int

實例以下:

package main

import (
    "fmt"
    "strings"
)
func main() {
    fmt.Println("子字符串出現次數:", strings.Count("hello world", "o"))
    fmt.Println("子字符串爲空時, 返回:", strings.Count("hello", ""))
}

運行結果:

子字符串出現次數: 2
子字符串爲空時, 返回: 6

重複操做

重複s字符串count次, 最後返回新生成的重複的字符串

func Repeat(s string, count int) string

實例以下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Repeat("嘀嗒", 4), "時針它不停在轉動")
}

運行結果:

嘀嗒嘀嗒嘀嗒嘀嗒 時針它不停在轉動

替換操做

在s字符串中, 把old字符串替換爲new字符串,n表示替換的次數,若是n<0會替換全部old子串。

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

實例以下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Replace("hel hel hel", "l", "llo", 2))
    fmt.Println(strings.Replace("hel hel hel", "l", "llo", -1))
}

運行結果:

hello hello hel
hello hello hello

刪除操做

刪除在s字符串的頭部和尾部中由cutset指定的字符, 並返回刪除後的字符串

func Trim(s string, cutset string) string

實例以下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Trim("   hello   ", " "))
}

運行結果:

hello

大小寫轉換

給定字符串轉換爲英文標題的首字母大寫的格式(不能正確處理unicode標點)

func Title(s string) string

返回將全部字母都轉爲對應的小寫版本的拷貝

func ToLower(s string) string

返回將全部字母都轉爲對應的大寫版本的拷貝

func ToUpper(s string) string

實例以下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Title("It is never too late to learn."))
    fmt.Println(strings.ToLower("It Is Never Too Late To Learn."))
    fmt.Println(strings.ToUpper("It is never too late to learn."))
}

運行結果:

It Is Never Too Late To Learn.
it is never too late to learn.
IT IS NEVER TOO LATE TO LEARN.

字符串前綴後綴

判斷字符串是否包含前綴prefix,大小寫敏感

func HasPrefix(s, prefix string) bool

判斷s是否有後綴字符串suffix,大小寫敏感

func HasSuffix(s, suffix string) bool

實例以下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println("前綴是以hello開頭的:", strings.HasPrefix("helloworld", "hello"))
    fmt.Println("後綴是以world開頭的:", strings.HasSuffix("helloworld", "world"))
}

運行結果:

前綴是以hello開頭的: true
後綴是以world開頭的: true

字符串分割

用去掉s中出現的sep的方式進行分割,會分割到結尾,並返回生成的全部片斷組成的切片(每個sep都會進行一次切割,即便兩個sep相鄰,也會進行兩次切割)。若是sep爲空字符,Split會將s切分紅每個unicode碼值一個字符串。

func Split(s, sep string) []string

返回將字符串按照空白(unicode.IsSpace肯定,能夠是一到多個連續的空白字符)分割的多個字符串。若是字符串所有是空白或者是空字符串的話,會返回空切片。

func Fields(s string) []string

實例以下:

//若是要分割的字符串位於字符串兩端,會多出一個空字符串

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println("Split 函數的用法")
    fmt.Printf("%q\n", strings.Split("Linux,Python,Golang,Java", ","))
    fmt.Printf("%q\n", strings.Split("a mountain a temple", "a "))
    fmt.Printf("%q\n", strings.Split(" abc ", ""))
    fmt.Printf("%q\n", strings.Split("", "oldboy"))
    fmt.Println("Fields 函數的用法")
    fmt.Printf("Fields are: %q\n", strings.Fields(" Linux Python Golang  Java "))
}

運行結果:

Split 函數的用法
["Linux" "Python" "Golang" "Java"]
["" "mountain " "temple"]    
[" " "a" "b" "c" " "]
[""]
Fields 函數的用法
Fields are: ["Linux" "Python" "Golang" "Java"]
相關文章
相關標籤/搜索