ZetCode

Golang Regexp.Split

最后修改于 2025 年 4 月 20 日

本教程将介绍如何在Go中使用Regexp.Split方法。我们将涵盖正则表达式分割基础知识,并提供实际示例。

一个 正则表达式 是一个定义搜索模式的字符序列。它用于在字符串中进行模式匹配。

Regexp.Split方法根据正则表达式的匹配项将字符串分割成子字符串。它比strings.Split更强大。

基本的Regexp.Split示例

Regexp.Split最简单的用法是按固定分隔符分割。这里我们分割一个逗号分隔的字符串。

basic_split.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`,`)
    text := "apple,banana,cherry,date"
    
    parts := re.Split(text, -1)
    for _, part := range parts {
        fmt.Println(part)
    }
}

我们编译一个简单的逗号模式并分割输入字符串。-1表示返回所有子字符串,包括空字符串。

按多个分隔符分割

当您需要按多个可能的分隔符分割时,正则表达式分割就显得尤为强大。此示例按逗号、分号或空格分割。

multi_delimiter.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`[,;\s]+`)
    text := "apple,banana; cherry  date;elderberry"
    
    parts := re.Split(text, -1)
    for _, part := range parts {
        fmt.Println(part)
    }
}

该模式匹配一个或多个逗号、分号或空格字符。这可以优雅地处理项目之间不规则的间距。

限制分割次数

您可以通过指定一个正整数作为第二个参数来控制分割的次数。这会限制返回的子字符串的数量。

limit_splits.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\s+`)
    text := "one two three four five"
    
    // Split into max 3 parts
    parts := re.Split(text, 3)
    for i, part := range parts {
        fmt.Printf("Part %d: %s\n", i+1, part)
    }
}

输出最多会有3个子字符串。其余的分隔符将保留在最后一个子字符串中。

带捕获组的分割

当正则表达式包含捕获组时,匹配的组会包含在结果中。此示例演示了捕获分隔符。

capture_groups.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(\s*)([;,]\s*)`)
    text := "apple; banana,cherry;date"
    
    parts := re.Split(text, -1)
    for i, part := range parts {
        fmt.Printf("Part %d: %q\n", i, part)
    }
}

输出包含捕获组匹配的空字符串。理解这种行为对于处理结果非常重要。

按不同的行尾分割行

不同的操作系统使用不同的行尾符。在将文本分割成行时,正则表达式可以处理所有变体。

line_endings.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\r?\n|\r`)
    text := "line1\nline2\r\nline3\rline4"
    
    lines := re.Split(text, -1)
    for _, line := range lines {
        fmt.Println(line)
    }
}

该模式匹配 \n、\r\n 或 \r。这可以一致地处理 Unix、Windows 和旧的 Mac 行尾符。

按复杂的单词边界分割

对于自然语言处理,您可能需要根据标点符号按单词边界进行分割。此示例展示了如何操作。

word_boundaries.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`[\s,.!?;:]+`)
    text := "Hello, there! How are you today?"
    
    words := re.Split(text, -1)
    for _, word := range words {
        fmt.Println(word)
    }
}

该模式匹配一个或多个空格或标点符号字符。这可以从文本中生成干净的单词标记。

分割时保留分隔符

有时您需要分割字符串,但同时将分隔符保留在输出中。这需要一种创造性的方法,因为Go的regexp包的Split方法不会在结果中保留分隔符。相反,我们使用FindAllStringIndex结合字符串切片来实现此功能。

keep_delimiters.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`[,;]`)
    text := "apple,banana;cherry"

    // Split the string while keeping the delimiters
    parts := re.FindAllStringIndex(text, -1)
    result := []string{}
    lastIndex := 0

    for _, indices := range parts {
        start, end := indices[0], indices[1]
        result = append(result, text[lastIndex:start]) // Add part before the delimiter
        result = append(result, text[start:end])       // Add the delimiter
        lastIndex = end
    }
    result = append(result, text[lastIndex:]) // Add the final part after the last delimiter

    for _, part := range result {
        fmt.Println(part)
    }
}

此示例演示了如何将字符串分割成子字符串,同时在输出中保留分隔符。正则表达式[,;]匹配分隔符,FindAllStringIndex方法检索它们在字符串中的位置。利用这些位置,程序对原始字符串进行切片,并构造一个包含子字符串和分隔符的数组。

输出显示分隔符嵌入在分割部分中,这使得该方法对于分隔符对于进一步处理或格式化至关重要的场景非常有用。这种方法可以适应各种模式和分隔符,在处理结构化文本时提供了灵活性。

来源

Go regexp 包文档

本教程通过使用正则表达式分割字符串的实际示例,涵盖了Go中的Regexp.Split方法。

作者

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

列出所有 Go 教程