golang筆記——string


  任何語言中,字符串操作API都是非常重要的,有些還是熟記比較好,當然如果記不住可以去看源碼文件,不得不說GO語言源碼看起來非常舒服。

  可以使用反引號代替雙引號,來表示原生的字符串,即不進行轉義,尤其適合用於表示正則表達式、路徑字符串、JSON串。

  每個Unicode碼點都使用同樣的大小32bit來表示。這種方式比較簡單統一,但是它會浪費很多存儲空間,因為大數據計算機可讀的文本是ASCII字符,本來每個ASCII字符只需要8bit或1字節就能表示。而且即使是常用的字符也遠少於65,536個,也就是說用16bit編碼方式就能表達常用字符。

  UTF8是一個將Unicode碼點編碼為字節序列的變長編碼。UTF8編碼由Go語言之父Ken Thompson和Rob Pike共同發明的,現在已經是Unicode的標准。UTF8編碼使用1到4個字節來表示每個Unicode碼點,ASCII部分字符只使用1個字節,常用字符部分使用2或3個字節表示。每個符號編碼后第一個字節的高端bit位用於表示總共有多少編碼個字節。如果第一個字節的高端bit為0,則表示對應7bit的ASCII字符,ASCII字符每個字符依然是一個字節,和傳統的ASCII編碼兼容。如果第一個字節的高端bit是110,則說明需要2個字節;后續的每個高端bit都以10開頭。更大的Unicode碼點也是采用類似的策略處理。 

許多類型都會定義一個String方法,因為當使用fmt包的打印方法時,將會優先使用該類型對應的String方法返回的結果打印

 

  go語言默認使用UTF-8編碼,對Unicode的支持非常好。其它語言中一般都提供獲取字符串長度的函數,但實際上是獲取字節個數,但獲取 Unicode 碼點個數就可能有些麻煩,比如注冊帳號時,無視中英文限制長度時,就要獲取Unicode碼點個數。GO語言內置了方法:

import "unicode/utf8"

s := "Hello, 世界"
fmt.Println(len(s))                    // "13"
fmt.Println(utf8.RuneCountInString(s)) // "9"

  而遍歷輸出這些字符是這樣的:

for i := 0; i < len(s); {
    r, size := utf8.DecodeRuneInString(s[i:])
    fmt.Printf("%d\t%c\n", i, r)
    i += size
}

每一次調用DecodeRuneInString函數都返回一個r和長度,r對應字符本身,長度對應r采用UTF8編碼后的編碼字節數目。實際上,Go語言的range循環在處理字符串的時候,會自動隱式解碼UTF8字符串。

for i, r := range "Hello, 世界" {
    fmt.Printf("%d\t%q\t%d\n", i, r, r)
}

string接受到[]rune的類型轉換,可以將一個UTF8編碼的字符串解碼為Unicode字符序列。

如果遇到非法的unicode字符,會解析成 \uFFFD,它是一個特殊符號,遇到它就要注意了。

標准庫中有四個包對字符串處理尤為重要:bytes、strings、strconv和unicode包。strings包提供了許多如字符串的查詢、替換、比較、截斷、拆分和合並等功能。

bytes包也提供了很多類似功能的函數,但是針對和字符串有着相同結構的[]byte類型。因為字符串是只讀的,因此逐步構建字符串會導致很多分配和復制。在這種情況下,使用bytes.Buffer類型將會更有效,稍后我們將展示。

strconv包提供了布爾型、整型數、浮點數和對應字符串的相互轉換,還提供了雙引號轉義相關的轉換。

unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等類似功能,它們用於給字符分類。每個函數有一個單一的rune類型的參數,然后返回一個布爾值。而像ToUpper和ToLower之類的轉換函數將用於rune字符的大小寫轉換。所有的這些函數都是遵循Unicode標准定義的字母、數字等分類規范。strings包也有類似的函數,它們是ToUpper和ToLower,將原始字符串的每個字符都做相應的轉換,然后返回新的字符串。

  字節數組 []byte 和 string 可以互相轉換,[]byte本質是一個數組(切片?),string是一個常量。bytes包和strings包提供了很多類似的函數,都是為了效率出發,避免轉換。bytes包還提供了Buffer類型用於字節slice的緩存。一個Buffer開始是空的,但是隨着string、byte或[]byte等類型數據的寫入可以動態增長,一個bytes.Buffer變量並不需要處理化,因為零值也是有效的:

當向bytes.Buffer添加任意字符的UTF8編碼時,最好使用bytes.Buffer的WriteRune方法,但是WriteByte方法對於寫入類似'['和']'等ASCII字符則會更加有效。

 

  字符串操作相關的API大多封裝在 strings 包里,下面列一些常見的

func Count(s, sep string) int

  獲取指定子字符串的個數

func Contains(s, substr string) bool

  判斷是否包括某子字符串

func ContainsAny(s, chars string) bool

  判斷是否包括某字符串中的做任意一個字符,只要包括其中任意一個字符則返回true

func EqualFold(s, t string) bool

  忽略大小寫時,判斷兩個字符串是否相等。

func Fields(s string) []string

  其實就是其它語言中的 Splite 函數,分隔字符串的,這個是按空格分隔。

func Split(s, sep string) []string

  按指定字符分隔字符串

func FieldsFunc(s string, f func(rune) bool) []string

  更強大的自定義分隔字符串,使用函數作為參數

    s := "a,b,c d,e,f"
    slice1 := strings.FieldsFunc(s, func(c rune) bool {
        if c == ',' || c == ' ' {
            return true
        }
        return false
    })
    print_array(slice1)

func HasPrefix(s, prefix string) bool

  判斷是否以某字符串開頭

func HasSuffix(s, suffix string) bool

  判斷是否以某字符串結尾

 

  

接合這個看源碼吧  http://www.widuu.com/archives/01/939.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM