Go 1.24正式版本发布在即, 本次版本中strings包增加了5个新方法, 可以在某些场景下更方便地处理字符串。 以下对这些方法的基本使用进行介绍。


Lines


Lines 返回一个迭代器,该迭代器遍历字符串 s 中以换行符结束的行,生成的行包括它们的终止换行符。如果 s 为空,迭代器将不产生任何行;如果 s 末尾没有换行符,则最后生成的行将不以换行符结束。该迭代器为一次性使用。


func ExampleLines() {
    // 标准情况
    text := "Hello\nWorld\nGo Programming\n"
    fmt.Println("1. Using for-range loop (recommended):")
    for line := range strings.Lines(text) {
        fmt.Printf("%q\n", line)
    }

    // 末尾没有换行符
    text2 := "First line\nSecond line"
    fmt.Println("\n2. Text without trailing newline:")
    for line := range strings.Lines(text2) {
        fmt.Printf("%q\n", line)
    }


    // Output:
    // 1. Using for-range loop (recommended):
    // "Hello\n"
    // "World\n"
    // "Go Programming\n"
    //
    // 2. Text without trailing newline:
    // "First line\n"
    // "Second line"
}


SplitSeq和SplitAfterSeq


SplitSeq 返回一个迭代器,遍历字符串 s 中由分隔符 sep 分隔的所有子字符串。迭代器生成的字符串与使用 Split(s, sep) 返回的字符串相同,但不构造切片。该迭代器为一次性使用。

func ExampleSplitSeq() {
    // 使用特定分隔符分割字符串
    s := "a,b,c,d"
    fmt.Println("Split string by comma:")
    for part := range strings.SplitSeq(s, ",") {
        fmt.Printf("%q\n", part)
    }

    // 使用空分隔符分割成字符
    text := "Hello世界"
    fmt.Println("\nSplit into characters:")
    for char := range strings.SplitSeq(text, "") {
        fmt.Printf("%q\n", char)
    }

    // Output:
    // Split string by comma:
    // "a"
    // "b"
    // "c"
    // "d"
    //
    // Split into characters:
    // "H"
    // "e"
    // "l"
    // "l"
    // "o"
    // "世"
    // "界"
}


SplitAfterSeq 返回一个迭代器,遍历字符串 s 中每个分隔符 sep 后的子字符串。迭代器生成的字符串与使用 SplitAfter(s, sep) 返回的字符串相同,但不构造切片。该迭代器为一次性使用。

func ExampleSplitAfterSeq() {
    // 使用分隔符分割(并会保留分隔符)
    s := "a,b,c,d"
    fmt.Println("Split string by comma (keeping separators):")
    for part := range strings.SplitAfterSeq(s, ",") {
        fmt.Printf("%q\n", part)
    }

    // Output:
    // Split string by comma (keeping separators):
    // "a,"
    // "b,"
    // "c,"
    // "d"
}




两个方法的主要区别在于分割后的子字符串是否包含分隔符


FieldsSeq和FieldsFuncSeq


func ExampleFieldsSeq() {
    // 通过空格分割
    text := "The quick brown fox"
    fmt.Println("Split string into fields:")
    for word := range strings.FieldsSeq(text) {
        fmt.Printf("%q\n", word)
    }

    // 通过多个空格来分割
    textWithSpaces := "  lots   of   spaces  "
    fmt.Println("\nSplit string with multiple spaces:")
    for word := range strings.FieldsSeq(textWithSpaces) {
        fmt.Printf("%q\n", word)
    }

    // Output:
    // Split string into fields:
    // "The"
    // "quick"
    // "brown"
    // "fox"
    //
    // Split string with multiple spaces:
    // "lots"
    // "of"
    // "spaces"
}


FieldsSeqSplitSeqSplitAfterSeq 的主要区别在于:

  1. 分割方式不同:
  2. SplitSeqSplitAfterSeq 使用指定的分隔符(separator)来分割字符串
  3. FieldsSeq 自动使用空白字符(whitespace)作为分隔符,包括空格、制表符、换行符等
  4. 处理连续分隔符的方式不同:
  5. SplitSeqSplitAfterSeq 会保留空字符串(在连续分隔符之间)
  6. FieldsSeq 会忽略连续的空白字符,不会产生空字符串

举个例子:

// SplitSeq
"a  b" 使用 " " 分割会产生: ["a", "", "b"]

// FieldsSeq
"a  b" 会产生: ["a", "b"]


func ExampleFieldsFuncSeq() {
    // 使用空格分割 (和FieldsSeq效果类似)
    text := "The quick brown fox"
    fmt.Println("Split on whitespace:")
    for word := range strings.FieldsFuncSeq(text, unicode.IsSpace) {
        fmt.Printf("%q\n", word)
    }

    // 根据数字切割
    mixedText := "abc123def456ghi"
    fmt.Println("\nSplit on digits:")
    for word := range strings.FieldsFuncSeq(mixedText, unicode.IsDigit) {
        fmt.Printf("%q\n", word)
    }

    // Output:
    // Split on whitespace:
    // "The"
    // "quick"
    // "brown"
    // "fox"
    //
    // Split on digits:
    // "abc"
    // "def"
    // "ghi"
}

即相比于FieldsSeq, FieldsFuncSeq可以使用任意函数来定义分割条件,而不仅限于空白字符

即:

// FieldsSeq - 只能按空白分割
"a b c" -> ["a", "b", "c"]

// FieldsFuncSeq - 可以按任意条件分割
// 按数字分割
"abc123def456" -> ["abc", "def"] 

// 按大写字母分割
"helloWorldGo" -> ["hello", "orld", "o"]

// 当然也可以模拟 FieldsSeq 的行为
text := "a b c"
FieldsFuncSeq(text, unicode.IsSpace) // 结果与 FieldsSeq(text) 相同

好文收藏
38 声望6 粉丝

好文收集