Golang regexp.QuoteMeta
最后修改于 2025 年 4 月 20 日
本教程解释了如何在Go中使用regexp.QuoteMeta函数。我们将介绍它的用途,并提供转义正则表达式元字符的实际示例。
一个正则表达式是定义搜索模式的字符序列。像.、*和+这样的特殊字符在正则表达式模式中具有特殊含义。
regexp.QuoteMeta函数会转义字符串中的所有正则表达式元字符。返回的字符串是一个匹配文字文本的正则表达式。
基本的regexp.QuoteMeta示例
regexp.QuoteMeta最简单的用法是转义包含正则表达式元字符的字符串。这使得它们能够被字面匹配。
package main
import (
"fmt"
"regexp"
)
func main() {
str := `Hello. there!*`
quoted := regexp.QuoteMeta(str)
fmt.Println("Original:", str)
fmt.Println("Quoted:", quoted)
re := regexp.MustCompile(quoted)
fmt.Println("Match:", re.MatchString("Hello. there!*"))
}
该函数转义了.和*字符。编译后的正则表达式将匹配字面字符串 "Hello. there!*"。
转义用户输入
从用户输入构建正则表达式模式时,请务必使用QuoteMeta。这可以防止正则表达式注入攻击。
package main
import (
"fmt"
"regexp"
)
func main() {
userInput := `file*.txt`
safePattern := regexp.QuoteMeta(userInput) + `$`
re := regexp.MustCompile(safePattern)
fmt.Println("Match file.txt:", re.MatchString("file.txt"))
fmt.Println("Match file1.txt:", re.MatchString("file1.txt"))
fmt.Println("Match file*.txt:", re.MatchString("file*.txt"))
}
不加引用时,该模式将匹配任何以".txt"结尾的文件。加引用后,它只匹配字面字符串 "file*.txt"。
转义路径分隔符
文件路径通常包含正则表达式元字符。此示例显示了如何安全地匹配路径。
package main
import (
"fmt"
"regexp"
)
func main() {
path := `/usr/local/bin/go`
quotedPath := regexp.QuoteMeta(path)
re := regexp.MustCompile(quotedPath)
fmt.Println("Match exact path:", re.MatchString(path))
fmt.Println("Match similar path:", re.MatchString("/usr/local/bin/golang"))
}
正斜杠被转义,确保正则表达式匹配确切的路径字符串。如果不加引用,斜杠将被解释为正则表达式分隔符。
与其他模式结合使用
QuoteMeta可以与其他正则表达式模式结合使用。这里我们创建一个匹配字面前缀的模式。
package main
import (
"fmt"
"regexp"
)
func main() {
prefix := `user[input]`
suffix := `_\d+`
pattern := regexp.QuoteMeta(prefix) + suffix
re := regexp.MustCompile(pattern)
tests := []string{
"user[input]_123",
"user_input_456",
"user[input]X789",
}
for _, test := range tests {
fmt.Printf("%s: %t\n", test, re.MatchString(test))
}
}
前缀中的方括号被转义,而后缀使用正则表达式元字符。只有同时匹配这两个部分的字符串才会被匹配。
为替换字符串转义
在使用正则表达式替换时,QuoteMeta可确保字面替换。此示例演示了安全的字符串替换。
package main
import (
"fmt"
"regexp"
)
func main() {
text := "Replace $10 with $$10"
pattern := `\$\d+`
replacement := regexp.QuoteMeta("$$20")
re := regexp.MustCompile(pattern)
result := re.ReplaceAllString(text, replacement)
fmt.Println("Original:", text)
fmt.Println("Replaced:", result)
}
替换字符串包含一个美元符号,该符号通常具有特殊含义。转义可确保它被视为字面美元符号。
性能比较
此示例比较了使用和不使用QuoteMeta进行匹配,以显示正确转义的重要性。
package main
import (
"fmt"
"regexp"
)
func main() {
search := `file[1].txt`
// Unsafe match (might not work as expected)
unsafeRe := regexp.MustCompile(search)
fmt.Println("Unsafe match:", unsafeRe.MatchString(search))
// Safe match with QuoteMeta
safeRe := regexp.MustCompile(regexp.QuoteMeta(search))
fmt.Println("Safe match:", safeRe.MatchString(search))
// What happens with special characters
testInput := "file1txt"
fmt.Println("Unsafe match wrong input:", unsafeRe.MatchString(testInput))
fmt.Println("Safe match wrong input:", safeRe.MatchString(testInput))
}
未加引用的模式会匹配意外的输入,因为方括号是正则表达式元字符。加引用的模式仅匹配确切的字面字符串。
转义复杂字符串
此示例显示了QuoteMeta如何处理包含多个特殊字符的字符串。
package main
import (
"fmt"
"regexp"
)
func main() {
complexStr := `^$.*+?()|[]{}-\`
quoted := regexp.QuoteMeta(complexStr)
fmt.Println("Original:", complexStr)
fmt.Println("Quoted:", quoted)
re := regexp.MustCompile(quoted)
fmt.Println("Match original:", re.MatchString(complexStr))
fmt.Println("Match modified:", re.MatchString("^$X.*+?()|[]{}-\\"))
}
所有特殊的正则表达式元字符都已正确转义。编译后的模式将只匹配包含所有特殊字符的原始字符串。
来源
本教程通过转义字符串中的正则表达式元字符的实际示例,介绍了Go中的regexp.QuoteMeta函数。