如何使用Golang与正则表达式提取并存储多种标签内容
解决Golang正则提取多平级标签内容的问题
你的正则表达式存在两个关键问题,导致只能提取到第一个标签:
- 贪婪匹配过度:
(.|\n)*是贪婪模式,会尽可能匹配最长的内容——从第一个<tag1>开始,直接匹配到最后一个</tag2>的结束位置,所以只会返回一个包含所有内容的匹配结果。 - 标签分组不关联:前后的
(tag1|tag2)是独立分组,逻辑上允许出现<tag1>...</tag2>这种不合法的标签匹配,虽然你的示例里没出现,但这是潜在的bug。
修正方案
使用非贪婪匹配+反向引用的正则表达式,解决上述问题:
re := regexp.MustCompile(`<(tag1|tag2)>([\s\S]*?)</\1>`)
各部分作用:
[\s\S]*?:\s匹配所有空白字符(包括换行),\S匹配非空白字符,合起来覆盖任意字符;?开启非贪婪模式,匹配到最近的闭合标签就停止,不会过度匹配。\1:反向引用第一个分组捕获的标签名(tag1或tag2),确保闭合标签和开头标签严格一致,避免不匹配的情况。
完整Golang代码示例
package main import ( "fmt" "regexp" ) func main() { input := "<tag1>hello\nmy name is Matt</tag1><tag2>goodbye!</tag2>" // 编译修正后的正则 re := regexp.MustCompile(`<(tag1|tag2)>([\s\S]*?)</\1>`) // 提取所有匹配结果,-1表示不限制匹配数量 matches := re.FindAllStringSubmatch(input, -1) // 遍历输出每个标签的名称和内容 for _, match := range matches { fmt.Printf("标签: %s\n内容: %s\n\n", match[1], match[2]) } }
运行后输出:
标签: tag1 内容: hello my name is Matt 标签: tag2 内容: goodbye!
额外提示
如果你的场景中存在标签嵌套(比如<tag1><tag2>...</tag2></tag1>),正则表达式就不再适用了——正则无法处理嵌套结构的层级关系,这种情况建议使用Go标准库的encoding/xml或者第三方HTML解析库来处理。但针对你给出的平级标签场景,上述正则完全可以满足需求。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

