字符串底层以及常用方法

1.1. 字符串

在编写程序时,使用字符串来进行文本的处理,例如:

package main
​
import "fmt"func main() {
  var name string = "alex"
  fmt.Printf(name)
​
  title := "生活要想过得去,头上总得带点绿"
  fmt.Printf(title)
}

字符串的底层存储

计算机中所有的操作和数据最终都是二进制,即:1000100001011...

Go语言中的字符串是utf-8编码的序列。

package main
​
import "fmt"func main() {
    // unicode字符集:文字 -> 码点(ucs4, 4个字节表示)
    // utf-8编码,对unicode字符集的码点进行编码最终得到:1000100001
  var name string = "武沛齐"
    fmt.Printf(name)
}

课上代码示例:

package main
​
import (
  "fmt"
  "strconv"
  "unicode/utf8"
)
​
func main() {
  // 1. 本质是utf-8编码的序列
  var name string = "武沛齐"// 武 => 11100110 10101101 10100110
  fmt.Println(name[0], strconv.FormatInt(int64(name[0]), 2))
  fmt.Println(name[1], strconv.FormatInt(int64(name[1]), 2))
  fmt.Println(name[2], strconv.FormatInt(int64(name[2]), 2))
​
  // 武 => 11100110 10110010 10011011
  fmt.Println(name[3], strconv.FormatInt(int64(name[3]), 2))
  fmt.Println(name[4], strconv.FormatInt(int64(name[4]), 2))
  fmt.Println(name[5], strconv.FormatInt(int64(name[5]), 2))
​
  // 武 => 11101001 10111101 10010000
  fmt.Println(name[6], strconv.FormatInt(int64(name[6]), 2))
  fmt.Println(name[7], strconv.FormatInt(int64(name[7]), 2))
  fmt.Println(name[8], strconv.FormatInt(int64(name[8]), 2))
​
  // 2. 获取字符串的长度:9(字节长度)
  fmt.Println(len(name))
​
  // 3. 字符串转换为一个"字节集合"
  byteSet := []byte(name)
  fmt.Println(byteSet) // [230,173,166,230,178,155,233,189,144]// 4. 字节的集合转换为字符串
  byteList := []byte{230, 173, 166, 230, 178, 155, 233, 189, 144}
  targetString := string(byteList)
  fmt.Println(targetString)
​
  // 5. 将字符串转换为 unicode字符集码点的集合    6b66 ->  武  6c9b->沛   9f50->齐
  tempSet := []rune(name)
  fmt.Println(tempSet) // [27494 27803 40784]
  fmt.Println(tempSet[0], strconv.FormatInt(int64(tempSet[0]), 16))
  fmt.Println(tempSet[1], strconv.FormatInt(int64(tempSet[1]), 16))
  fmt.Println(tempSet[2], strconv.FormatInt(int64(tempSet[2]), 16))
​
  // 6. "rune集合" 转换 为字符串
  runeList := []rune{27494, 27803, 40784}
  targetName := string(runeList)
  fmt.Println(targetName)
​
  // 7. 长度的处理(获取字符长度)
  runeLength := utf8.RuneCountInString(name)
  fmt.Println(runeLength)
}

字符串常见功能

字符串属于在程序中最常见用的数据类型,所以Go中为字符串提供了很多常见的操作。

1 获取长度

package main
​
import (
   "fmt"
   "unicode/utf8"
)
​
func main() {
   var name string = "武沛齐"
​
   fmt.Println( len(name) )                    // 获取 字节 长度,输出:8
   fmt.Println( utf8.RuneCountInString(name) ) // 获取字符长度,输出:3
}

2 是否以xx开头

package main
​
import (
   "fmt"
   "strings"
)
​
func main() {
   name := "武沛齐"
​
   result := strings.HasPrefix(name, "武")
​
   fmt.Println(result) // 输出:true
}

3 是否以xx结尾

package main
​
import (
  "fmt"
  "strings"
)
​
func main() {
  name := "武沛齐"
​
  result := strings.HasSuffix(name, "齐")
​
  fmt.Println(result) // 输出:true
}

4 是否包含

package main
​
import (
   "fmt"
   "strings"
)
​
func main() {
   name := "抬老子的意大利炮来"
   result := strings.Contains(name, "老子")
​
   fmt.Println(result) // 输出:true
}

5 变大写

package main
​
import (
   "fmt"
   "strings"
)
​
func main() {
   name := "wupeiqi"
​
   result := strings.ToUpper(name)
​
   fmt.Println(result) // 输出:WUPEIQI
}
// 注意:result是大写;name依然是小写。

6 变小写

package main
​
import (
  "fmt"
  "strings"
)
​
func main() {
  name := "WUPEIQI"
​
  result := strings.ToLower(name)
​
  fmt.Println(result) // 输出:wupeiqi
}

7 去两边

package main
​
import (
   "fmt"
   "strings"
)
​
func main() {
   name := "wupeiqi"
​
   result1 := strings.TrimRight(name, "qi") // 去除右边的qi
   result2 := strings.TrimLeft(name, "w")   // 去除左边的w
   result3 := strings.Trim(name, "w")       // 去除两边的w
​
   fmt.Println(result1, result2, result3) // 输出:wupe upeiqi upeiqi
}

8 替换

package main
​
import (
   "fmt"
   "strings"
)
​
func main() {
   name := "wupeipeiqi"
​
   result1 := strings.Replace(name, "pei", "PE", 1)  // 找到pei替换为PE,从左到右找第一个替换
   result2 := strings.Replace(name, "pei", "PE", 2)  // 找到pei替换为PE,从左到右找前两个替换
   result3 := strings.Replace(name, "pei", "PE", -1) // 找到pei替换为PE,替换所有
​
   fmt.Println(result1, result2, result3)
}

9 分割

package main
​
import (
   "fmt"
   "strings"
)
​
func main() {
   name := "抬老子的意大利的炮来"
   result := strings.Split(name, "的")
​
   // 根据`的`进行切割,获取一个切片(类似于一个数组)
   fmt.Println(result) // [ 抬老子, 意大利, 炮来 ]
}

10 拼接

可以使用 + 让两个字符串进行拼接,但这样的拼接效率会非常的低,不建议使用,建议大家使用以下的方式:

package main
​
import (
  "bytes"
  "fmt"
  "strings"
)
​
func main() {
  // 不建议
  message := "我爱" + "北京天安门"
  fmt.Println(message)
​
  // 建议:效率高一些
  dataList := []string{"我爱", "北京天安门"}
  result := strings.Join(dataList, "")
  fmt.Println(result) // 我爱北京天安门// 建议:效率更高一些(go 1.10之前)
  var buffer bytes.Buffer
  buffer.WriteString("你想")
  buffer.WriteString("我干")
  buffer.WriteString("他")
  data := buffer.String()
  fmt.Print(data)
​
  // 建议:效率更更更更高一些(go 1.10之后)
  var builder strings.Builder
  builder.WriteString("哈哈哈")
  builder.WriteString("去你的吧")
  value := builder.String()
  fmt.Print(value)
}

11 string转换为int

package main
​
import (
  "fmt"
  "strconv"
)
​
func main() {
  num := "666"// 内部调用的就是 ParseInt
  var data, _ = strconv.Atoi(num)
  fmt.Println(data)

    // 整型转字符串(strconv.ParseInt 和 strconv.FormatInt 可用处理进制转换)
    // 十进制:整型; 其他进制:字符串形式 
    var result, err = strconv.ParseInt(num, 10, 32)
  fmt.Println(result, err)
}

12 int转换为string

package main
​
import (
  "fmt"
  "strconv"
)
​
func main() {
  var result = strconv.Itoa(888)
  fmt.Println(result)
}

13 字符串 和 “字节集合”

package main
​
import (
  "fmt"
  "strconv"
  "unicode/utf8"
)
​
func main() {
​
  var name string = "武沛齐"// 字符串转换为一个"字节集合"
  byteSet := []byte(name)
  fmt.Println(byteSet) // [230,173,166,230,178,155,233,189,144]// 字节的集合转换为字符串
  byteList := []byte{230, 173, 166, 230, 178, 155, 233, 189, 144}
  targetString := string(byteList)
  fmt.Println(targetString)
​
}

14 字符串 和 “rune集合”

package main
​
import (
  "fmt"
  "strconv"
  "unicode/utf8"
)
​
func main() {
​
  var name string = "武沛齐"// 将字符串转换为 unicode字符集码点的集合    6b66 ->  武  6c9b->沛   9f50->齐
  tempSet := []rune(name)
  fmt.Println(tempSet) // [27494 27803 40784]
  fmt.Println(tempSet[0], strconv.FormatInt(int64(tempSet[0]), 16))
  fmt.Println(tempSet[1], strconv.FormatInt(int64(tempSet[1]), 16))
  fmt.Println(tempSet[2], strconv.FormatInt(int64(tempSet[2]), 16))
​
  // "rune集合" 转换 为字符串
  runeList := []rune{27494, 27803, 40784}
  targetName := string(runeList)
  fmt.Println(targetName)
}

15 string 和 字符

package main
​
import (
  "fmt"
  "unicode/utf8"
)
​
func main() {
  // 数字转字符串
  v1 := string(65)
  fmt.Println(v1) // A

    v2 := string(27494)
  fmt.Println(v2) // 武

  // 字符串转数字
  v3, size := utf8.DecodeRuneInString("A")
  fmt.Println(v3, size) // 65    1

    v4, size := utf8.DecodeRuneInString("武")
  fmt.Println(v4, size) // 27494 3
​
}

应用场景:生成一个随机数,然后调用string得到一个随机的字符。

索引切片和循环

package main
​
import "fmt"func main() {
  var name string = "武沛齐"// 1. 索引获取字节
  v1 := name[0]
  fmt.Println(v1)  // 230// 2. 切片获取字节区间
  v2 := name[0:3]
  fmt.Println(v2)  // 武// 3. 手动循环获取所有字节
    /*
        0 230
        1 173
        2 166
        3 230
        4 178
        5 155
        6 233
        7 189
        8 144
    */
  for i := 0; i < len(name); i++ {
    fmt.Println(i, name[i]) 
  }
​
  // 4. for range 循环获取所有字符
    /*
        0 27494 武
        3 27803 沛
        6 40784 齐
  */
  for index, item := range name {
        fmt.Println(index, item, string(item))
  }
​
  // 5.转换成rune集合 [27494,27803,40784]
  dataList := []rune(name)
  fmt.Println(dataList[0], string(dataList[0]))
​
}

results matching ""

    No results matching ""