ZetCode

Go 字符串函数

最后修改时间 2024 年 4 月 11 日

在本文中,我们将介绍如何在 Golang 中使用字符串函数。

strings 包实现了处理 UTF-8 编码字符串的简单函数。

Go 字符串重复

repeat 函数返回一个新字符串,该字符串由指定次数的字符串副本组成。

repeat_fun.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    w := "falcon"
    fmt.Println(strings.Repeat(w+" ", 5))
}

我们将给定的字符串重复五次。

$ go run repeat_fun.go
falcon falcon falcon falcon falcon

Go 字符串比较

Compare 函数按字典顺序比较两个字符串。要以不区分大小写的方式比较两个字符串,我们使用 EqualFold 函数。

comparing.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    w1 := "falcon"
    w2 := "Falcon"

    if strings.Compare(w1, w2) == 0 {

        fmt.Println("The words are equal")
    } else {

        fmt.Println("The words are not equal")
    }

    if strings.EqualFold(w1, w2) {

        fmt.Println("The words are equal")
    } else {

        fmt.Println("The words are not equal")
    }
}

该示例比较了两个字符串。

$ go run comparing.go
The words are not equal
The words are equal

Go 字符串 Replace 和 ReplaceAll

Replace 函数返回一个字符串的副本,其中前 n 个字符串被替换,而 ReplaceAll 返回一个副本,其中所有字符串都被替换。

replacing.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    msg := "I saw a fox in the forest. The fox had brown fur."

    output := strings.Replace(msg, "fox", "wolf", 2)
    fmt.Println(output)

    output2 := strings.ReplaceAll(msg, "fox", "wolf")
    fmt.Println(output2)
}

示例将 fox 替换为 wolf。

$ go run replacing.go
I saw a wolf in the forest. The wolf had brown fur.
I saw a wolf in the forest. The wolf had brown fur.

Go 字符串索引

Index 函数返回找到的第一个子字符串的索引,而 LastIndex 查找最后一个索引。

indexing.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    msg := "I saw a fox in the forest. The fox had brown fur. I like foxes."

    idx1 := strings.Index(msg, "fox")
    fmt.Println(idx1)

    idx2 := strings.LastIndex(msg, "fox")
    fmt.Println(idx2)
}

我们查找单词“fox”的第一个和最后一个索引。

$ go run indexing.go
8
57

Go 字符串计数

Count 函数计算在字符串中找到的子字符串的数量。

counting.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    word := "wood"

    c1 := "o"
    c2 := "w"

    n1 := strings.Count(word, c1)
    fmt.Printf("# of %s in %s: %d\n", c1, word, n1)

    n2 := strings.Count(word, c2)
    fmt.Printf("# of %s in %s: %d\n", c2, word, n2)
}

我们计算在“wood”中找到的字符 'o' 和 'w' 的次数。

$ go run counting.go
# of o in wood: 2
# of w in wood: 1

Go 字符串 ToUpper, ToLower, Title

ToLower 函数返回字符串的小写副本,而 ToUpper 返回字符串的大写版本。Title 函数返回给定字符串的标题化副本(仅首字母大写)。

lower_upper.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    msg := "and old falcon"
    msg2 := "čerešňa"

    fmt.Println(strings.Title(msg))
    fmt.Println(strings.ToUpper(msg))

    fmt.Println(strings.ToUpper(msg2))
    fmt.Println(strings.Title(msg2))
}

我们使用这些函数更改两个单词的大小写。

$ go run lower_upper.go
And Old Falcon
AND OLD FALCON
ČEREŠŇA
Čerešňa

Go 字符串 HasPrefix 和 HasSuffix

HasPrefix 函数检查字符串是否以给定的前缀开头。HasSufffix 函数检查字符串是否以给定的后缀结尾。

starts_ends.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    words := []string {"sky", "lot", "car", "wood", "cloud",
        "cup", "war", "wind", "near", "tell", "cheer", "coin", "book"}

    for _, word := range words {

        if strings.HasPrefix(word, "c") {

            fmt.Println(word)
        }
    }

    fmt.Println("----------------------")

    for _, word := range words {

        if strings.HasSuffix(word, "r") {

            fmt.Println(word)
        }
    }
}

我们有一个单词切片。我们遍历切片的元素,并打印所有以“c”开头并以“r”结尾的单词。

$ go run starts_ends.go
car
cloud
cup
cheer
coin
----------------------
car
war
near
cheer

Go 字符串 Contains 和 ContainsRune

Contains 函数检查给定的子字符串是否存在于字符串中。ConstainsRune 检查 Unicode 代码点是否在字符串中。

contains.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    msg := "a blue 🐋"
    r := '🐋'

    if strings.ContainsRune(msg, r) {

        fmt.Println("yes")
    } else {

        fmt.Println("no")
    }

    fmt.Println("-----------------")

    if strings.Contains(msg, "🐋") {

        fmt.Println("yes")
    } else {

        fmt.Println("no")
    }
}

我们使用这两个方法来确定字符串中是否存在海豚符文。

$ go run contains.go
yes
-----------------
yes

Go 字符串修剪函数

Trim 返回字符串的一个切片,其中删除了 cutset 中包含的所有前导和尾随 Unicode 代码点。TrimLeft 函数返回字符串的一个切片,其中删除了 cutset 中包含的所有前导 Unicode 代码点。TrimRight 函数返回字符串的一个切片,其中删除了 cutset 中包含的所有尾随 Unicode 代码点。

trim_funs.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    msg := ".an old falcon!"
    cutset := ".!"

    msg2 := strings.Trim(msg, cutset)
    fmt.Println(msg2)

    msg3 := strings.TrimLeft(msg, cutset)
    fmt.Println(msg3)

    msg4 := strings.TrimRight(msg, cutset)
    fmt.Println(msg4)
}

我们使用这三个函数从字符串中删除句点和感叹号。

$ go run trim_funs.go
an old falcon
an old falcon!
.an old falcon

TrimSpace 函数删除所有前导和尾随的空格字符。TrimFunc 返回字符串的一个切片,其中删除了满足提供函数的所有前导和尾随 Unicode 代码点。

trim_funs2.go
package main

import (
    "fmt"
    "strings"
    "unicode"
)

func main() {

    msg := "\t\tand old falcon\n"

    msg2 := strings.TrimSpace(msg)
    fmt.Println(msg2)

    msg3 := strings.TrimFunc(msg, trimSpace)
    fmt.Println(msg3)
}

func trimSpace(r rune) bool {

    return !unicode.IsLetter(r)
}

在代码示例中,我们使用提到的函数删除了字符串的前导和尾随空格。


TrimPrefix 函数返回不带提供的领先前缀字符串的字符串,而 TrimSuffix 返回不带尾随后缀字符串的字符串。

trim_funs3.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    msg := "--and old falcon--"

    msg2 := strings.TrimPrefix(msg, "--")
    fmt.Println(msg2)

    msg3 := strings.TrimSuffix(msg, "--")
    fmt.Println(msg3)
}

示例演示了如何从字符串的开头和结尾删除“--”字符。

$ go run trim_funs3.go
and old falcon--
--and old falcon

Go 字符串 Split

Split 函数将切片分解为由给定分隔符分隔的所有子字符串,并返回分隔符之间的子字符串切片。

split_fun.go
package main

import (
    "fmt"
    "log"
    "strconv"
    "strings"
)

func main() {

    msg := "3,4,5,6,7,8,9,10,11"

    data := strings.Split(msg, ",")
    fmt.Printf("%v\n", data)

    var sum = 0
    for _, e := range data {

        val, err := strconv.Atoi(e)

        if err != nil {
            log.Fatal(err)
        }

        sum += val
    }

    fmt.Println(sum)
}

我们有一个由逗号分隔的整数值字符串。该字符串按逗号分割成几部分。使用 strconv.Atoi 将字符串部分转换为整数,然后将整数相加。

$ go run split_fun.go
[3 4 5 6 7 8 9 10 11]
63

Go 字符串 Join

Join 函数将切片参数的元素连接起来,创建一个单一的字符串。

join_fun.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    words := []string{"an", "old", "falcon", "in", "the", "sky"}

    msg := strings.Join(words, " ")
    fmt.Println(msg)
}

我们用空格字符连接切片中的单词。

Go 字符串 Fields

Fields 函数按一个或多个空格字符将给定字符串分割成几部分。它提供了一种方便的方式将字符串分割成单词。

thermopylae.txt
The Battle of Thermopylae was fought between an alliance of Greek city-states,
led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the
course of three days, during the second Persian invasion of Greece.

这是一个小的文本文件。

fields_fun.go
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "strings"
)

func main() {

    fileName := "thermopylae.txt"
    bs, err := ioutil.ReadFile(fileName)

    if err != nil {

        log.Fatal(err)
    }

    text := string(bs)
    fields := strings.Fields(text)

    for _, field := range fields {

        fmt.Println(strings.Trim(field, ".,"))
    }
}

我们将给定的文件读入一个字符串,并使用 Fields 将其分割成单词。我们还从单词中删除了句点和逗号字符。

$ go run fields_fun.go
The
Battle
of
Thermopylae
was
fought
between
an
alliance
of
Greek
city-states
...

Go 字符串 FieldsFun

FieldsFunc 函数在满足提供函数的每个 Unicode 代码点序列处分割字符串,并返回一个切片数组。

$ wget https://raw.githubusercontent.com/janbodnar/data/main/the-king-james-bible.txt

我们使用《英王钦定本圣经》。

read_freq.go
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "sort"
    "strings"
)

func main() {

    fileName := "the-king-james-bible.txt"

    bs, err := ioutil.ReadFile(fileName)

    if err != nil {

        log.Fatal(err)
    }

    text := string(bs)

    fields := strings.FieldsFunc(text, func(r rune) bool {

        return !('a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' || r == '\'')
    })

    wordsCount := make(map[string]int)

    for _, field := range fields {

        wordsCount[field]++
    }

    keys := make([]string, 0, len(wordsCount))

    for key := range wordsCount {

        keys = append(keys, key)
    }

    sort.Slice(keys, func(i, j int) bool {

        return wordsCount[keys[i]] > wordsCount[keys[j]]
    })

    for idx, key := range keys {

        fmt.Printf("%s %d\n", key, wordsCount[key])

        if idx == 10 {
            break
        }
    }
}

我们统计《英王钦定本圣经》中单词的频率。

fields := strings.FieldsFunc(text, func(r rune) bool {

    return !('a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' || r == '\'')
})

FieldsFunc 按非字母字符和撇号分割文本。这也将忽略所有诗句编号。

wordsCount := make(map[string]int)

for _, field := range fields {

    wordsCount[field]++
}

每个单词及其频率存储在 wordsCount 映射中。

keys := make([]string, 0, len(wordsCount))

for key := range wordsCount {

    keys = append(keys, key)
}

sort.Slice(keys, func(i, j int) bool {

    return wordsCount[keys[i]] > wordsCount[keys[j]]
})

为了按频率对单词进行排序,我们创建了一个新的 keys 切片。我们将所有单词放入其中,并按它们的频率值对它们进行排序。

for idx, key := range keys {

    fmt.Printf("%s %d\n", key, wordsCount[key])

    if idx == 10 {
        break
    }
}

我们打印圣经中出现频率最高的十个词。

$ go run word_freq.go
the 62103
and 38848
of 34478
to 13400
And 12846
that 12576
in 12331
shall 9760
he 9665
unto 8942
I 8854

来源

Go strings 包 - 参考

在本文中,我们介绍了 Go 的 strings 包中的字符串函数。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教学编程方面拥有十多年的经验。

列出所有 Go 教程