Go字符串实战

0 阅读6分钟

1.字符串实战:

1).中文字符串的截取:

在Go语言中.可以使用len()函数获取字符串的字节长度.其中英文占一个字节长度.中文占三个长度.可以使用"变量名[n]"获取字符串长度n+1个字节.返回这个字节的对应的Unicode码值(uint8类型).注意n的取值范围是[0,len(n)-1].

在Go语言中可以通过截取一个数组或字符串.但是当截取的字符串是中文时.可能会出现的问题是:由于中文一个字不只是由一个字节组成.所以直接通过切片获取可能会把一个中文的编码截成两半.结果导致最后一个字符是乱码.解决办法可以先将其转为[]rune类型.在截取后.转回字符串类型.

源码:

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    //生成一个字符串变量.
    str := "学习go字符串切片截取"
    //字符串长度.
    fmt.Println("字符串长度", utf8.RuneCountInString(str))
    //打印字节长度.
    fmt.Println("字节长度", len(str))
    //获取字符串前五个字符.
    s := str[0:5]
    fmt.Println(s)
    //将字符串转为rune类型.
    nameRune := []rune(str)
    //打印转换后的长度.
    fmt.Println(len(nameRune))
    fmt.Println("string=", string(nameRune[0:5]))
}

执行结果:

2).按单词或字节反转字符串:

在Go语言中国.如果要反转字符串.可以先将字符串转成rune数组类型.利用平行赋值的方式反转.再将rune数组转回字符串类型.

示例:

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    //定义字符串.
    str := "123456789abcde"
    resultStr := Reversal(str)
    fmt.Println(str)
    fmt.Println(resultStr)
}

// 反转字符串.
func Reversal(str string) (resultStr string) {
    //字符串转成rune数组.
    b := []rune(str)
    //遍历.
    for i := 0; i < len(b)/2; i++ {
       //交换.
       b[i], b[len(b)-i-1] = b[len(b)-i-1], b[i]
    }
    //转换为string类型.
    resultStr = string(b)
    return resultStr
}

执行结果:

3).生成随机字符串:

math/rand包实现了伪随机数生成器.可以生成整型和浮点型随机数.该包中根据生成伪随机数是否有种子.可以分为两类.

有种子:通常以时钟 输入输出等特殊节点作为参数进行初始化.该类型生成的随机数相比无种子时重复概率较低.

无种子:可以理解为此时种子为1.

示例:

package main

import (
    "fmt"
    "math/rand"
    "time"
    "unicode/utf8"
)

func main() {
    //获取3位随机字符串.
    randomString := GetRandomString(3)
    fmt.Println(randomString)
}

// 获取随机字符串.
func GetRandomString(l int) string {
    //声明字符串.
    str := "0123456789asdfghjklqwertyuiopzxcvbnm"
    //转换成数组
    bytes := []byte(str)
    result := []byte{}
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    for i := 0; i < l; i++ {
       result = append(result, bytes[r.Intn(len(bytes))])
    }
    return string(result)
}

执行结果:

4).crypto/rand包生成随机字符串:

如果对随机性要求高的话.可以用这个包生成(速度相对会慢一些).crypto/rand包实现了用于加解密安全的随机数生成器.

示例:

package main

import (
    "fmt"
    "math/rand"
    "time"
    "unicode/utf8"
)

func main() {
    str := "0123456789asdfghjklqwertyuiopzxcvbnm"
    bytes := []byte(str)
    //获取3位随机字符串.
    randomString := NewLenChars(3, bytes)
    fmt.Println(randomString)
}

func NewLenChars(length int, chars []byte) string {
    if length == 0 {
       return ""
    }
    clen := len(chars)
    if clen < 2 || clen > 256 {
       panic("wrong charset length forNewLenChars")
    }
    maxrb := 255 - (256 % clen)
    b := make([]byte, length)
    r := make([]byte, (length + length/4))
    i := 0
    for {
       if _, err := rand.Read(r); err != nil {
          panic("Error reading random bytes: " + err.Error())
       }
       for _, rb := range r {
          c := int(rb)
          if c > maxrb {
             //跳过此数字避免偏差.
             continue
          }
          b[i] = chars[c%clen]
          i++
          if i == length {
             return string(b)
          }
       }
    }
}

执行结果:

5).控制大小写:

Go语言转换所有字符串为大写或小写.

Go语言的strings包提供了ToLower()和ToUpper函数.用于将字符串转换成小写和大写.定义如下.

func ToUpper(s string)string   //转换为大写.

func ToLower(s string)string   //转换为小写.

Go语言区分大小的替换字符串:

可以通过regexp包的MustCompile()和ReplaceAllString()两个函数组合使用来处理实现区分大小写的替换字符串.

示例:

package main

import (
    "fmt"
    "math/rand"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    test := "I,Love,Go"
    str := test
    keywordSlice := strings.Split(str, ",")
    for _, v := range keywordSlice {
       reg := regexp.MustCompile("(?i)" + v)
       str := reg.ReplaceAllString(str, strings.ToUpper(v))
       fmt.Println(str)
    }
}

执行结果:

6).去除字符串收尾的空格:

Go语言strings包提供了TrimSpace()函数来去除字符串的空格.定义如下.

func Trim(s string) string

也可以用string包提供的Trim函数去除字符串空格.定义如下.

func Trim(s,cutset string)string

示例:

package main

import (
    "fmt"
    "math/rand"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    str := "  Go Advanced"
    str1 := strings.TrimSpace(str)
    str2 := strings.Trim(str, " ")
    fmt.Println(str)
    fmt.Println(str1)
    fmt.Println(str2)
}

执行结果:

image.png

7).生成CSV数据:

逗号分割值是指文件以纯文本形式存储表格数据(数字和文本).Go语言提供encoding/csv包来处理CSV数据.

示例:

package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    //创建一个名为"test.csv 的文件
    f, err := os.Create("test.csv")
    if err != nil {
       panic(err)
    }
    defer f.Close()
    //写入utf-8 bom
    f.WriteString("\xEF\xBB\xBF")
    //返回一个write对象.
    w := csv.NewWriter(f)
    //调用Write方法写入.
    w.Write([]string{"学号", "姓名", "分数"})
    w.Write([]string{"1", "it1", "99"})
    w.Write([]string{"2", "it2", "98"})
    w.Write([]string{"3", "it3", "97"})
    w.Flush()
}

执行结果:

运行代码会在代码所在的目录生成一个名为"test.csv的文件".打开如下.

image.png

8).解析CSV数据:

Go语言可以通过简单的逐行扫描输入并使用strings.Split()等函数解析CSV格式.Go语言提供了更好的方法.那就是用encoding/csv包来处理.包中的NewReader()函数返回Reader结构体.该结构体提供了读取CSV文件的api接口.

示例:

package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    file, err := os.Open("D:\\go\\test.csv")
    if err != nil {
       panic(err)
    }
    defer file.Close()
    reader := csv.NewReader(file)
    reader.Comma = ';'
    for {
       record, err := reader.Read()
       if err != nil {
          fmt.Println(err)
          break
       }
       fmt.Println(record)
    }
}

执行结果:

image.png

9).获取中文字符串:

获取中文字符串可以通过regexp包的MustCompile()函数来实现.regexp包实现了正则表达式搜索.

示例:

```
package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

// 匹配中文字符.
var cnRegexp = regexp.MustCompile("^[\u4e00-\u9fa5]$")

func main() {
    str := "我喜欢Go"
    StrFilerGetChinese(&str)
    fmt.Println(str)
}

func StrFilerGetChinese(src *string) {
    strNew := ""
    for _, c := range *src {
       if cnRegexp.MatchString(string(c)) {
          strNew += string(c)
       }
    }
    *src = strNew
}
```

执行结果:

image.png

10).指定函数分割字符串:

Go语言strings包中提供了一个名为FiledsFunc()的函数来分割字符串.方法定义如下.

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

示例:

package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    fn := func(c rune) bool {
       return strings.ContainsRune(",|/", c)
    }
    str := strings.FieldsFunc("Python,Jquery|Java,Go,C++/C", fn)
    fmt.Println(str)
}

执行结果:

image.png

11).合并与分割字符串:

Go语言strings提供了一个名为Join()的函数.定义如下.

func Join(elems []string,sep string)string

strings包提供了Split() SplitN() SplitAfter() SplitAfterN()四个函数来处理正则分割字符串.

示例:

package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    s := "I_Love_Go_Web"
    res := strings.Split(s, "_")
    for i := range res {
       fmt.Println(res[i])
    }
    fmt.Println("------------")
    res1 := strings.SplitN(s, "_", 2)
    for i := range res1 {
       fmt.Println(res1[i])
    }
    fmt.Println("------------")
    res2 := strings.SplitAfter(s, "_")
    for i := range res2 {
       fmt.Println(res2[i])
    }
    fmt.Println("------------")
    res3 := strings.SplitAfterN(s, "_", 2)
    for i := range res3 {
       fmt.Println(res3[i])
    }
}

执行结果:

image.png

12).按照指定函数截取字符串:

Go语言的strings包中提供了TrimFunc()函数截取字符串.定义如下.

func TrimFunc(s string,f func(rune)bool)string

示例:

package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    fn := func(c rune) bool {
       return strings.ContainsRune(",|/", c)
    }
    res := strings.TrimFunc("|/Shirdon Liao,/", fn)
    fmt.Println(res)
}

执行结果: