MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Go字符串处理函数

2022-12-203.9k 阅读

字符串拼接

在Go语言中,字符串拼接是常见操作。字符串是不可变的,每次拼接都会生成新的字符串。

使用 + 运算符

最直观的方式是使用 + 运算符来拼接字符串。例如:

package main

import (
    "fmt"
)

func main() {
    str1 := "Hello"
    str2 := " World"
    result := str1 + str2
    fmt.Println(result)
}

在这个例子中,我们简单地使用 + 运算符将两个字符串 str1str2 拼接在一起,结果为 "Hello World"。当拼接多个字符串时,使用 + 运算符会有性能问题,因为每次 + 操作都会创建新的字符串对象。

使用 fmt.Sprintf

fmt.Sprintf 函数可以格式化并拼接字符串。它类似于 printf 函数,但返回的是格式化后的字符串而不是输出到标准输出。示例如下:

package main

import (
    "fmt"
)

func main() {
    name := "Alice"
    age := 30
    result := fmt.Sprintf("Name: %s, Age: %d", name, age)
    fmt.Println(result)
}

上述代码中,fmt.Sprintf 根据格式化字符串 "Name: %s, Age: %d",将 nameage 转换为字符串并拼接在一起。%s 用于格式化字符串,%d 用于格式化整数。fmt.Sprintf 虽然方便,但性能不如 strings.Builder

使用 strings.Builder

strings.Builder 是Go 1.10引入的用于高效字符串拼接的结构体。它通过缓冲机制,减少了字符串创建的次数。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    var sb strings.Builder
    sb.WriteString("Hello")
    sb.WriteString(" ")
    sb.WriteString("World")
    result := sb.String()
    fmt.Println(result)
}

在上述代码中,我们首先创建了一个 strings.Builder 实例 sb。然后通过 WriteString 方法将多个字符串写入 sb。最后调用 String 方法获取拼接后的字符串。strings.Builder 适用于需要多次拼接字符串的场景,性能较高。

使用 bytes.Buffer

bytes.Buffer 也可以用于字符串拼接,它和 strings.Builder 类似,但功能更通用,不仅可以处理字符串,还可以处理字节切片。示例如下:

package main

import (
    "bytes"
    "fmt"
)

func main() {
    var buffer bytes.Buffer
    buffer.WriteString("Hello")
    buffer.WriteString(" ")
    buffer.WriteString("World")
    result := buffer.String()
    fmt.Println(result)
}

在这个例子中,我们创建了一个 bytes.Buffer 实例 buffer,并通过 WriteString 方法写入字符串。最后使用 String 方法获取拼接后的字符串。bytes.Buffer 适用于需要与字节操作交互的场景,例如处理网络数据等。

字符串查找

在Go语言中,查找字符串中的子串是常见需求。

strings.Contains

strings.Contains 函数用于判断一个字符串是否包含另一个子串。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "Hello World"
    subStr := "World"
    if strings.Contains(str, subStr) {
        fmt.Printf("字符串 %s 包含子串 %s\n", str, subStr)
    } else {
        fmt.Printf("字符串 %s 不包含子串 %s\n", str, subStr)
    }
}

上述代码中,strings.Contains 检查字符串 str 是否包含子串 subStr。如果包含则输出相应提示,否则输出另一条提示。

strings.Index

strings.Index 函数返回子串在字符串中第一次出现的索引位置,如果不存在则返回 -1。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "Hello World"
    subStr := "World"
    index := strings.Index(str, subStr)
    if index != -1 {
        fmt.Printf("子串 %s 在字符串 %s 中第一次出现的索引是 %d\n", subStr, str, index)
    } else {
        fmt.Printf("字符串 %s 中未找到子串 %s\n", str, subStr)
    }
}

在这个例子中,strings.Index 查找 subStrstr 中的索引位置,并根据结果输出不同的提示。

strings.LastIndex

strings.LastIndex 函数返回子串在字符串中最后一次出现的索引位置,如果不存在则返回 -1。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "Hello World, Hello Go"
    subStr := "Hello"
    index := strings.LastIndex(str, subStr)
    if index != -1 {
        fmt.Printf("子串 %s 在字符串 %s 中最后一次出现的索引是 %d\n", subStr, str, index)
    } else {
        fmt.Printf("字符串 %s 中未找到子串 %s\n", str, subStr)
    }
}

上述代码展示了 strings.LastIndex 的使用,它查找 subStrstr 中最后一次出现的位置。

字符串替换

字符串替换是修改字符串内容的常见操作。

strings.Replace

strings.Replace 函数用于将字符串中的指定子串替换为新的字符串。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "Hello World"
    oldSubStr := "World"
    newSubStr := "Go"
    result := strings.Replace(str, oldSubStr, newSubStr, -1)
    fmt.Println(result)
}

在这个例子中,strings.Replace 将字符串 str 中的 "World" 替换为 "Go"。最后一个参数 -1 表示替换所有匹配的子串。如果设为 1,则只替换第一次出现的子串。

strings.ReplaceAll

strings.ReplaceAll 是Go 1.11引入的函数,专门用于替换字符串中所有匹配的子串。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "Hello World, Hello Go"
    oldSubStr := "Hello"
    newSubStr := "Hi"
    result := strings.ReplaceAll(str, oldSubStr, newSubStr)
    fmt.Println(result)
}

上述代码中,strings.ReplaceAll 将字符串 str 中所有的 "Hello" 替换为 "Hi"

字符串分割

字符串分割是将一个字符串按照指定的分隔符拆分成多个子串。

strings.Split

strings.Split 函数根据指定的分隔符将字符串拆分成字符串切片。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "apple,banana,orange"
    separator := ","
    parts := strings.Split(str, separator)
    for _, part := range parts {
        fmt.Println(part)
    }
}

在这个例子中,strings.Split 根据逗号 "," 将字符串 str 拆分成多个子串,并存储在切片 parts 中。然后通过循环打印每个子串。

strings.SplitN

strings.SplitN 函数和 strings.Split 类似,但可以指定拆分的最大次数。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "apple,banana,orange,grape"
    separator := ","
    parts := strings.SplitN(str, separator, 3)
    for _, part := range parts {
        fmt.Println(part)
    }
}

上述代码中,strings.SplitN 将字符串 str 按照逗号拆分,最多拆分 3 次,所以切片 parts 最多包含 3 个元素。

字符串修剪

字符串修剪用于去除字符串两端的空白字符或指定字符。

strings.TrimSpace

strings.TrimSpace 函数用于去除字符串两端的空白字符(包括空格、制表符、换行符等)。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "   Hello World   "
    trimmedStr := strings.TrimSpace(str)
    fmt.Println(trimmedStr)
}

在这个例子中,strings.TrimSpace 去除了字符串 str 两端的空白字符,得到 "Hello World"

strings.Trim

strings.Trim 函数用于去除字符串两端指定的字符。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "###Hello World###"
    cutset := "#"
    trimmedStr := strings.Trim(str, cutset)
    fmt.Println(trimmedStr)
}

上述代码中,strings.Trim 根据 cutset 去除字符串 str 两端的 '#' 字符,得到 "Hello World"

strings.TrimLeftstrings.TrimRight

strings.TrimLeft 函数去除字符串左边(开头)指定的字符,strings.TrimRight 函数去除字符串右边(结尾)指定的字符。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "###Hello World###"
    cutset := "#"
    leftTrimmed := strings.TrimLeft(str, cutset)
    rightTrimmed := strings.TrimRight(str, cutset)
    fmt.Println(leftTrimmed)
    fmt.Println(rightTrimmed)
}

在这个例子中,strings.TrimLeft 去除字符串 str 左边的 '#' 字符,strings.TrimRight 去除字符串 str 右边的 '#' 字符。

字符串大小写转换

在Go语言中,可以方便地对字符串进行大小写转换。

strings.ToUpper

strings.ToUpper 函数将字符串中的所有字符转换为大写。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "hello world"
    upperStr := strings.ToUpper(str)
    fmt.Println(upperStr)
}

在这个例子中,strings.ToUpper 将字符串 str 中的所有字符转换为大写,得到 "HELLO WORLD"

strings.ToLower

strings.ToLower 函数将字符串中的所有字符转换为小写。示例如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "HELLO WORLD"
    lowerStr := strings.ToLower(str)
    fmt.Println(lowerStr)
}

上述代码中,strings.ToLower 将字符串 str 中的所有字符转换为小写,得到 "hello world"

字符串长度获取

获取字符串的长度在很多场景下都有用。

len 函数

在Go语言中,使用内置的 len 函数可以获取字符串的字节长度。示例如下:

package main

import (
    "fmt"
)

func main() {
    str := "Hello"
    length := len(str)
    fmt.Println(length)
}

在这个例子中,len(str) 返回字符串 str 的字节长度,对于 "Hello",长度为 5。需要注意的是,如果字符串包含非ASCII字符,len 函数返回的是字节长度而不是字符个数。例如:

package main

import (
    "fmt"
)

func main() {
    str := "你好"
    length := len(str)
    fmt.Println(length)
}

上述代码中,"你好" 这两个中文字符在UTF - 8编码下每个字符占3个字节,所以 len(str) 返回 6。如果要获取字符个数,需要使用 utf8.RuneCountInString 函数。

使用 utf8.RuneCountInString 获取字符个数

utf8.RuneCountInString 函数用于获取字符串中的Unicode字符个数。示例如下:

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    str := "你好"
    charCount := utf8.RuneCountInString(str)
    fmt.Println(charCount)
}

在这个例子中,utf8.RuneCountInString(str) 返回字符串 str 中的Unicode字符个数,对于 "你好",字符个数为 2。

字符串与字节切片转换

在Go语言中,字符串和字节切片之间的转换经常用到。

字符串转字节切片

可以使用 []byte 类型转换将字符串转换为字节切片。示例如下:

package main

import (
    "fmt"
)

func main() {
    str := "Hello"
    byteSlice := []byte(str)
    fmt.Println(byteSlice)
}

在这个例子中,[]byte(str) 将字符串 str 转换为字节切片 byteSlice

字节切片转字符串

可以通过直接使用 string 类型转换将字节切片转换为字符串。示例如下:

package main

import (
    "fmt"
)

func main() {
    byteSlice := []byte("Hello")
    str := string(byteSlice)
    fmt.Println(str)
}

上述代码中,string(byteSlice) 将字节切片 byteSlice 转换为字符串 str

字符串格式化

除了 fmt.Sprintf 外,Go语言还提供了其他字符串格式化相关的功能。

strconv.Itoastrconv.Atoi

strconv.Itoa 函数将整数转换为字符串,strconv.Atoi 函数将字符串转换为整数。示例如下:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    num := 123
    str := strconv.Itoa(num)
    fmt.Println(str)

    newNum, err := strconv.Atoi(str)
    if err == nil {
        fmt.Println(newNum)
    } else {
        fmt.Println("转换错误:", err)
    }
}

在这个例子中,strconv.Itoa(num) 将整数 num 转换为字符串 str。然后 strconv.Atoi(str) 将字符串 str 转换回整数 newNum,并检查是否转换成功。

strconv.FormatFloatstrconv.ParseFloat

strconv.FormatFloat 函数将浮点数转换为字符串,strconv.ParseFloat 函数将字符串转换为浮点数。示例如下:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    num := 3.14159
    str := strconv.FormatFloat(num, 'f', 2, 64)
    fmt.Println(str)

    newNum, err := strconv.ParseFloat(str, 64)
    if err == nil {
        fmt.Println(newNum)
    } else {
        fmt.Println("转换错误:", err)
    }
}

在上述代码中,strconv.FormatFloat(num, 'f', 2, 64) 将浮点数 num 格式化为保留两位小数的字符串 strstrconv.ParseFloat(str, 64) 将字符串 str 转换回浮点数 newNum 并检查错误。

字符串匹配

Go语言提供了正则表达式相关的库用于字符串匹配。

使用 regexp.MatchString

regexp.MatchString 函数用于判断字符串是否匹配指定的正则表达式。示例如下:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "Hello World"
    match, err := regexp.MatchString("Hello.*", str)
    if err == nil && match {
        fmt.Println("字符串匹配")
    } else {
        fmt.Println("字符串不匹配")
    }
}

在这个例子中,regexp.MatchString("Hello.*", str) 检查字符串 str 是否以 "Hello" 开头,后面跟随任意字符。如果匹配则输出 "字符串匹配",否则输出 "字符串不匹配"

使用 regexp.CompileRegexp.MatchString

regexp.Compile 函数用于编译正则表达式,返回一个 Regexp 对象,然后可以使用该对象的 MatchString 方法进行匹配。示例如下:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "Hello World"
    re, err := regexp.Compile("Hello.*")
    if err == nil {
        match := re.MatchString(str)
        if match {
            fmt.Println("字符串匹配")
        } else {
            fmt.Println("字符串不匹配")
        }
    } else {
        fmt.Println("正则表达式编译错误:", err)
    }
}

上述代码中,先使用 regexp.Compile 编译正则表达式,然后使用返回的 Regexp 对象的 MatchString 方法进行字符串匹配,并根据结果输出相应信息。如果编译正则表达式出错,会输出错误信息。

通过以上对Go语言字符串处理函数的详细介绍和代码示例,希望能帮助开发者更好地掌握和运用这些函数,在实际编程中高效地处理字符串相关的操作。无论是简单的拼接、查找,还是复杂的替换、正则匹配等,Go语言都提供了丰富且易用的工具。在实际应用中,需要根据具体场景选择合适的函数,以达到最佳的性能和功能需求。例如,在需要频繁拼接字符串的场景下,优先选择 strings.Builder 以提高性能;在进行复杂的文本模式匹配时,合理使用正则表达式相关函数。同时,要注意字符串编码相关的问题,特别是涉及非ASCII字符时,正确使用 utf8 相关函数来处理字符个数等问题。