Golang Regexp.ReplaceAll
最后修改于 2025 年 4 月 20 日
本教程将解释如何在 Go 中使用 Regexp.ReplaceAll 方法。我们将涵盖正则表达式替换基础知识并提供实际示例。
一个 正则表达式 是一个定义搜索模式的字符序列。它用于在字符串中进行模式匹配。
Regexp.ReplaceAll 方法将字节切片中正则表达式模式的所有匹配项替换为替换字符串。它返回修改后的切片。
基本 ReplaceAll 示例
ReplaceAll 最简单的用法是用固定字符串替换所有匹配项。这里我们将所有数字替换为星号。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\d`)
input := []byte("Order 12345 placed on 2025-04-20")
result := re.ReplaceAll(input, []byte("*"))
fmt.Println(string(result))
}
我们编译一个匹配任何数字的模式。ReplaceAll 将每个数字替换为一个星号。输入和输出都是字节切片。
在替换中使用捕获组
ReplaceAll 可以引用模式中的捕获组。此示例将日期格式从 YYYY-MM-DD 重格式化为 MM/DD/YYYY。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
input := []byte("Event date: 2025-04-20")
replacement := []byte("$2/$3/$1")
result := re.ReplaceAll(input, replacement)
fmt.Println(string(result))
}
该模式捕获年、月、日组。替换引用这些组来重新排列日期格式。$1 指的是第一个组。
使用函数进行条件替换
ReplaceAllFunc 允许为每个匹配项提供自定义逻辑。这里我们将句子中的特定单词大写。
package main
import (
"bytes"
"fmt"
"regexp"
"strings"
)
func main() {
re := regexp.MustCompile(`\b(go|rust|python)\b`)
input := []byte("I prefer go over rust, but python is also great.")
result := re.ReplaceAllFunc(input, func(match []byte) []byte {
return bytes.ToUpper(match)
})
fmt.Println(string(result))
}
函数将每个匹配项作为字节切片接收。我们将匹配的单词转换为大写。这比简单的字符串替换提供了更多的控制。
转义特殊字符
此示例演示了如何将特殊正则表达式字符替换为其转义版本。这在使用户输入进行处理时非常有用。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`([.*+?^${}()|\[\]\\])`)
input := []byte("Special chars: . * + ? { } ( ) [ ]")
result := re.ReplaceAll(input, []byte(`\$1`))
fmt.Println(string(result))
}
该模式匹配正则表达式元字符。每个匹配项都被其本身前面带有反斜杠的匹配项替换。$1 指的是匹配的字符。
移除敏感信息
ReplaceAll 可以红掉敏感数据。这里我们屏蔽信用卡号,同时保留最后四位数字。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\b(?:\d[ -]*?){13,16}\b`)
input := []byte("Card: 4111 1111 1111 1111")
result := re.ReplaceAll(input, []byte("[REDACTED]"))
fmt.Println(string(result))
}
该模式匹配各种信用卡号格式。所有匹配项都被替换为“[REDACTED]”。这有助于保护敏感信息。
模板式替换
此示例演示了如何使用正则表达式实现简单的模板替换。我们将占位符替换为实际值。
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\{\{(\w+)\}\}`)
input := []byte("Hello {{name}}, your balance is {{amount}}.")
replacements := map[string]string{
"name": "John",
"amount": "$100",
}
result := re.ReplaceAllFunc(input, func(match []byte) []byte {
// Fix the warning by directly using the map lookup
return []byte(replacements[string(re.ReplaceAll(match, []byte("$1")))])
})
fmt.Println(string(result))
}
该模式匹配 {{key}} 占位符。替换函数在映射中查找每个键。这创建了一个简单的模板系统。
性能优化
对于重复替换,预编译模式和替换可以提高性能。本例演示了该技术。
package main
import (
"fmt"
"regexp"
"time"
)
func main() {
re := regexp.MustCompile(`\b\w{4}\b`)
input := []byte("This text contains several four-letter words.")
replacement := []byte("****")
start := time.Now()
for i := 0; i < 10000; i++ {
re.ReplaceAll(input, replacement)
}
fmt.Println("Optimized:", time.Since(start))
start = time.Now()
for i := 0; i < 10000; i++ {
regexp.MustCompile(`\b\w{4}\b`).ReplaceAll(input, []byte("****"))
}
fmt.Println("Unoptimized:", time.Since(start))
}
基准测试表明,预编译模式和替换速度快得多。如果可能,避免为每个替换操作重新编译。
来源
本教程通过文本替换和转换的实际示例,涵盖了 Go 中的 Regexp.ReplaceAll 方法。