1. 程式人生 > 其它 >[golang]-go中字串操作和轉換簡介

[golang]-go中字串操作和轉換簡介

技術標籤:golanggolang字串

文章目錄

golang中字串是一種基本型別(string),是一個不可改變的UTF-8字元序列:

  • 一個ASCII碼佔用1個位元組;
  • 其它字元根據需要佔用2-4個位元組;

字串

字串建立後,就不可改變;即不允許修改。

宣告與初始化

golang支援兩種型別的字串字面量:

  • 解釋型字串:雙引號括起來的字串(""),轉義字元(如\n\r等)會被替換掉;
  • 非解釋型字串:用反引號(鍵盤左上角上的)括起來的字串,轉義字元不會被解釋且可跨行(原樣輸出);

字串宣告與初始化非常容易:

var s1 string
s2 := "hello"

多行字串使用反引號:

s := `hello
 world!
 line2`
fmt.Println(s)

長度

len()返回字串中的位元組數(非字元數目),索引操作s[i]返回字串s中第i個位元組的值(非Ascii碼返回對應位元組的數值)。要獲取對應字元數(包含非ASCII字元時)需要使用utf8.RuneCountInString

s1 := "W字元"
fmt.Println(len(s1))  // 7 (一個漢字3個位元組)
fmt.Println(utf8.
RuneCountInString(s1)) // 3

拼接

golang中有多種字串拼接方法:

  • 加號(+):最常用、方便的,但每次拼接都會生成一個新的字串,效率較低;
  • fmt.Sprintf():通過格式化字串方式拼接;
  • strings.Join():可以指定拼接時的間隔符;
  • bytes.Buffer:可變大小的位元組緩衝區,提供方便地讀寫操作;
  • strings.Builder:通過write方法高效地構造字串,最小化記憶體拷貝;

一般簡單拼接直接使用+,字串陣列/切片拼接為字串時用Join,多條不相關字串拼接時用Builder。

var buff bytes.Buffer
buff.WriteString
("hello") buff.WriteRune('字') buff.WriteString("符") fmt.Println(buff.String()) // hello字元 var build strings.Builder build.WriteString("hello") build.WriteRune('字') build.WriteString("符") fmt.Println(build.String()) // hello字元

子串

go中可通過切片方式快速獲取子串s=src[low:high](指定索引範圍,‘左含右不含’)。索引不能越界,否則會導致panic異常。

s1 := "abcdef"
fmt.Println(s1[1:4],s1[1:],s1[:1]) // bcd bcdef a

遍歷

有兩種遍歷方式:下標與range。下標方式遍歷時,輸出的是每個位元組;要輸出對應的Unicode字元,需要通過range方式。

s1 := "W字元"
// 輸出7個數值(每個位元組對應數值)
for i:=0; i<len(s1); i++{
	fmt.Println(s1[i])
}

// 輸出三個字元(分別:W 字 符)
for i, v:=range s1{
	fmt.Println(i, string(v))
}

修改

golang中字串內容預設不能修改,若要修改需要轉換為[]byte或[]rune型別修改後再轉回:

s1 := "W字元"
b1 := []byte(s1)
fmt.Println(len(b1)) // 7
b1[0] = 'M'
fmt.Println(string(b1)) // M字元

r1 := []rune(s1)
fmt.Println(len(r1)) // 3
r1[1] = '世'
fmt.Println(string(r1)) //W世符

strings包

strings中包含了一些常用的字串操作函式,在涉及到字串修改時,返回新的串。

  • 前後綴:HasPrefix、HasSuffix;
  • 是否包含:Contains;
  • 大小寫轉換:ToLower、ToUpper、Title;
  • 修剪:Trim、Trimleft、TrimRight;
  • 拼接拆分:Join、Split、Fields(根據空白分割);
  • 查詢位置(-1表示表示未找到):Index、LastIndex、IndexRune;
  • 統計數量:Count;
  • 重疊串:Repeat,重複n次生成新的串;
  • 替換:Replace,可指定替換數量,負數表示全部替換;

Map

func Map(mapping func(rune) rune, s string) string,根據mapping函式修改s中的字元,並返回修改後新的串;若mapping返回負值,則刪除對應字元。

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..."))

Reader

用於讀取字串,實現了io.Reader、io.ReaderAt、io.Seeker、io.WriterTo、io.ByteScanner、io.RuneScanner。

r := strings.NewReader("abcdefghijklmn")
fmt.Println("total len:", r.Len())   // 14
var buf []byte
buf = make([]byte, 5)
readLen, err := r.Read(buf)
fmt.Println("read len:", readLen) // 5
if err != nil {
	fmt.Println("error:", err)
}
fmt.Println(string(buf))            // abcde
fmt.Println("remain len:", r.Len())	// 9   讀取到了5個 剩餘未讀是14-5
fmt.Println("size:", r.Size()) 		// 14   字串的長度

Replacer

用於字串替換;placer中包含要替換字串的列表,且是執行緒安全的:

r := strings.NewReplacer("<", "&lt;", ">", "&gt;")
fmt.Println(r.Replace("This is <b>HTML</b>!")) // This is &lt;b&gt;HTML&lt;/b&gt;!

strconv包

strconv包用於字串與其它型別間的轉換:

  • 整數轉字串:strconv.FormatInt、strconv.FormatUint、strconv.Itoa(相當於FormatInt(i, 10));
  • 布林轉字串(“true” 或 “false”):strconv.FormatBool;
  • 浮點轉字串:strconv.FormatFloat;
  • 字串轉整數:strconv.ParseInt、strconv.ParseUint、strconv.Atoi(相當於ParseInt(s, 10, 0));
  • 字串轉布林:strconv.ParseBool(1,t,T,TRUE,true,True為真;0,f,F,FALSE,false,False為假);
  • 字串轉浮點:strconv.ParseFloat;
  • appendXXX:在[]byte後追加對應型別;

在轉換時,會出現兩種型別的錯誤:

  • ErrRange:表示值超過了型別能表示的最大範圍。
  • ErrSyntax:表示語法錯誤。

字串轉整數

func ParseInt(s string, base int, bitSize int)(i int64, err error)

  • s:要轉換的字串
  • base:進位制(2~36 進位制),0根據字串判斷進位制(0x:16,0:8,其它:10);
  • bitSize:指定整數型別(0:int、8:int8、16:int16、32:int32、64:int64)

常用的Atoi,是一個簡易版,相當於ParseInt(s, 10, 0)

浮點數轉字串

func FormatFloat(f float64, fmt byte, prec, bitSize int) string

  • f:要轉換的浮點數
  • fmt:格式標記(b、e、E、f、g、G)
  • prec:精度(數字部分的長度,不包括指數部分)
  • bitSize:指定浮點型別(32:float32、64:float64)

格式標記:

  • ‘b’ (-ddddp±ddd,二進位制指數)
  • ‘e’ (-d.dddde±dd,十進位制指數)
  • ‘E’ (-d.ddddE±dd,十進位制指數)
  • ‘f’ (-ddd.dddd,沒有指數)
  • ‘g’ (‘e’:大指數,‘f’:其它情況)
  • ‘G’ (‘E’:大指數,‘f’:其它情況)
f := 100.123456789
fmt.Println(strconv.FormatFloat(f, 'b', 5, 32)) // 13123382p-17
fmt.Println(strconv.FormatFloat(f, 'e', 5, 32)) // 1.00123e+02
fmt.Println(strconv.FormatFloat(f, 'E', 5, 32)) // 1.00123E+02
fmt.Println(strconv.FormatFloat(f, 'f', 5, 32)) // 100.12346
fmt.Println(strconv.FormatFloat(f, 'g', 5, 32)) // 100.12
fmt.Println(strconv.FormatFloat(f, 'G', 5, 32)) // 100.12