go 的 `regexp` 包不支持重复捕获组的多次匹配结果(即无法通过单个带 `+` 的捕获组获取所有子匹配),因此原正则仅返回整体匹配和最后一次子组捕获;正确做法是使用无捕获、全局匹配的简单模式 `\d+:\d+` 提取全部分数。
在 Go 中解析体育比分(如篮球首节比分 “102:72 (28:17, 27:15, 24:14, 23:26)”)时,开发者常误以为可通过嵌套重复捕获组(例如 (?:(\d+:\d+)(?:,\s)?)+)一次性提取所有时间-分数对。但需明确:Go 的 regexp 基于 RE2 引擎,不支持“重复捕获组的多次独立捕获值”——每次重复会覆盖前一次的子匹配内容,最终只保留最后一次成功捕获的结果。
这就是为什么原始代码:
var FirstQuarterBasketballRegexp = regexp.MustCompile(`^(\d+:\d+)\s\((?:(\d+:\d+)(?:,\s)?)+\)$`)
调用 FindAllStringSubmatch 后仅返回长度为 3 的切片:
- 索引 0:完整匹配字符串(”102:72 (28:17, 27:15, 24:14, 23:26)”)
- 索引 1:第一个捕获组 (\d+:\d+)(主比分 “102:72″)
- 索引 2:第二个捕获组 (\d+:\d+)(因重复覆盖,仅剩最后一次匹配 “23:26″)
✅ 正确解法是放弃复杂结构化捕获,改用扁平、可枚举的全局匹配模式: