ZetCode

Golang Regexp.ReplaceAllFunc

最后修改于 2025 年 4 月 20 日

本教程将介绍如何在 Go 中使用 Regexp.ReplaceAllFunc 方法。我们将涵盖使用自定义函数进行正则表达式替换,并提供实际示例。

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

Regexp.ReplaceAllFunc 方法使用自定义函数来生成替换字符串,从而替换正则表达式模式的所有匹配项。这提供了灵活的字符串操作功能。

基本 ReplaceAllFunc 示例

ReplaceAllFunc 最简单的用法是将匹配的文本转换为大写。这演示了定义替换函数的**基本模式**。

basic_replace.go
package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    re := regexp.MustCompile(`\b\w+\b`)
    text := "hello world from go"
    
    result := re.ReplaceAllFunc([]byte(text), func(match []byte) []byte {
        return []byte(strings.ToUpper(string(match)))
    })
    
    fmt.Println(string(result)) // HELLO WORLD FROM GO
}

我们匹配单词边界并将每个单词转换为大写。替换函数接收每个匹配项并返回转换后的版本。

条件替换

ReplaceAllFunc 允许基于匹配内容进行条件替换。在这里,我们仅在数字小于 5 时将数字替换为其单词形式。

conditional_replace.go
package main

import (
    "fmt"
    "regexp"
    "strconv"
)

func main() {
    re := regexp.MustCompile(`\d+`)
    text := "I have 3 apples and 10 oranges"
    
    result := re.ReplaceAllFunc([]byte(text), func(match []byte) []byte {
        num, _ := strconv.Atoi(string(match))
        if num < 5 {
            words := []string{"zero", "one", "two", "three", "four"}
            return []byte(words[num])
        }
        return match
    })
    
    fmt.Println(string(result)) // I have three apples and 10 oranges
}

该函数检查每个数字匹配项,将较小的数字转换为单词,而将较大的数字保持不变。这展示了动态替换逻辑。

复杂转换

我们可以对匹配项执行复杂的转换。此示例将日期格式从 MM/DD/YYYY 转换为 YYYY-MM-DD。

date_transform.go
package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    re := regexp.MustCompile(`(\d{2})/(\d{2})/(\d{4})`)
    text := "Start date: 04/20/2025, End date: 12/31/2025"
    
    result := re.ReplaceAllFunc([]byte(text), func(match []byte) []byte {
        parts := strings.Split(string(match), "/")
        return []byte(parts[2] + "-" + parts[0] + "-" + parts[1])
    })
    
    fmt.Println(string(result)) // Start date: 2025-04-20, End date: 2025-12-31
}

替换函数会拆分匹配的日期并重新排列各个部分。这展示了在替换过程中解析和重构匹配的文本。

递增数字

ReplaceAllFunc 可以修改文本中的数值。在这里,我们将字符串中找到的所有数字加 1。

increment_numbers.go
package main

import (
    "fmt"
    "regexp"
    "strconv"
)

func main() {
    re := regexp.MustCompile(`\d+`)
    text := "Version 1, Revision 3, Page 42"
    
    result := re.ReplaceAllFunc([]byte(text), func(match []byte) []byte {
        num, _ := strconv.Atoi(string(match))
        return []byte(strconv.Itoa(num + 1))
    })
    
    fmt.Println(string(result)) // Version 2, Revision 4, Page 43
}

每个匹配的数字都被转换为整数,递增,然后转换回字符串。这展示了替换过程中的数值操作。

Markdown 到 HTML 转换

我们可以使用 ReplaceAllFunc 进行简单的文本标记转换。此示例将 Markdown 加粗语法转换为 HTML strong 标签。

markdown_to_html.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\*\*(.*?)\*\*`)
    text := "This is **important** and **urgent**"
    
    result := re.ReplaceAllFunc([]byte(text), func(match []byte) []byte {
        content := match[2 : len(match)-2] // Remove ** markers
        return []byte("" + string(content) + "")
    })
    
    fmt.Println(string(result)) // This is important and urgent
}

该函数提取 ** 标记之间的文本,并将其包装在 HTML strong 标签中。这展示了在替换过程中进行内容提取。

密码混淆

ReplaceAllFunc 可用于敏感数据混淆。此示例在配置文件字符串中隐藏密码。

password_obfuscation.go
package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    re := regexp.MustCompile(`password=["'](.*?)["']`)
    text := `user="admin" password="secret123" role="admin"`
    
    result := re.ReplaceAllFunc([]byte(text), func(match []byte) []byte {
        parts := strings.Split(string(match), "=")
        return []byte(parts[0] + `="*******"`)
    })
    
    fmt.Println(string(result)) // user="admin" password="*******" role="admin"
}

密码值被星号替换,同时保留配置结构。这展示了如何安全地处理敏感数据。

模板变量扩展

我们可以使用 ReplaceAllFunc 进行模板变量扩展。此示例将 ${var} 模式替换为 map 中的值。

template_expansion.go
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\$\{(\w+)\}`)
    text := "Hello ${name}, your balance is ${amount}"
    vars := map[string]string{
        "name":   "John",
        "amount": "$100",
    }
    
    result := re.ReplaceAllFunc([]byte(text), func(match []byte) []byte {
        key := string(match[2 : len(match)-1]) // Extract variable name
        return []byte(vars[key])
    })
    
    fmt.Println(string(result)) // Hello John, your balance is $100
}

该函数在 map 中查找每个变量名,并将模板模式替换为相应的值。这展示了动态内容插入。

来源

Go regexp.ReplaceAllFunc 文档

本教程通过使用自定义函数进行灵活的字符串替换的实际示例,介绍了 Go 中的 Regexp.ReplaceAllFunc 方法。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出所有 Go 教程