
在 Go 语言中处理多行文本的正则表达式时,换行符常常会导致意外的匹配结果。
text := `first line
second line
third line`
// 看似正确但可能失效的正则
pattern := "first.*third"
matched, _ := regexp.Match(pattern, []byte(text))
fmt.Println(matched) // false.不匹配换行符\n 和 \r\n 的平台差异(?s) 标志(推荐)// 启用单行模式(让 . 匹配换行符)
pattern := `(?s)first.*third`
matched, _ := regexp.Match(pattern, []byte(text))
fmt.Println(matched) // true[\s\S] 字符类// 匹配任意字符(包括换行)
pattern := `first[\s\S]*third`
matched, _ := regexp.Match(pattern, []byte(text))
fmt.Println(matched) // true(?m)// 处理多行文本时的行首行尾
pattern := `(?m)^line\d$`
matches := regexp.MustCompile(pattern).FindAllString(text, -1)func extractComments(code string) []string {
pattern := `(?s)/\*.*?\*/`
re := regexp.MustCompile(pattern)
return re.FindAllString(code, -1)
}
// 测试
code := `
/* 这是一个
多行注释 */
func main() {
/* 另一个注释 */
}
`
comments := extractComments(code)func parseLogEntry(log string) []LogEntry {
pattern := `(?m)^(\d{4}-\d{2}-\d{2})\s+(.*)$`
re := regexp.MustCompile(pattern)
matches := re.FindAllStringSubmatch(log, -1)
var entries []LogEntry
for _, match := range matches {
entries = append(entries, LogEntry{
Date: match[1],
Content: match[2],
})
}
return entries
}// 好的做法
var commentRegex = regexp.MustCompile(`(?s)/\*.*?\*/`)
func process(input string) {
matches := commentRegex.FindAllString(input, -1)
// ...
}// 避免回溯过多
pattern := `(?s)/\*.*?\*/` // 使用非贪婪模式
// 而不是
pattern := `(?s)/\*.*\*/` // 贪婪模式可能导致性能问题// 处理跨平台换行符
pattern := `(?s)line1[\r\n]+line2`
// 或者
pattern := `(?s)line1\R+line2`// 启用 Unicode 支持
pattern := `(?s)(?U)first.*third`// 非贪婪匹配
pattern := `(?s)".*?"`
// 贪婪匹配
pattern := `(?s)".*"`(?s): 单行模式(?m): 多行模式(?i): 忽略大小写(?U): Unicode 支持\R 匹配通用换行调试技巧
// 打印正则匹配过程
debug := regexp.MustCompile(pattern)
fmt.Printf("Pattern: %q\n", debug.String())
fmt.Printf("Groups: %d\n", debug.NumSubexp())处理 Go 语言中的正则表达式换行符问题,关键在于:
(?s) 标志的作用本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。