package flashscore import ( "regexp" "strconv" "strings" ) type Surface string type Sex string const ( SurfaceHard Surface = "hard" SurfaceClay Surface = "clay" SurfaceGrass Surface = "grass" SurfaceCarpet Surface = "carpet" SexMen = "men" SexWomen = "women" ) var reBreakpoints = regexp.MustCompile(`(\d+)%\s*\((\d+)/(\d+)`) type Breakpoints struct { Qty int // всего сколько было брейкпоинтов Converted int // реализованных Percent int // процент реализации } // parseBreakpoints - извлекает статистику по брейкпоинтам из строки вида "50% (0/4)" func parseBreakpoints(str string) *Breakpoints { groups := reBreakpoints.FindStringSubmatch(str) if len(groups) == 4 { qty, _ := strconv.Atoi(groups[3]) converted, _ := strconv.Atoi(groups[2]) percent, _ := strconv.Atoi(groups[1]) return &Breakpoints{ Qty: qty, Converted: converted, Percent: percent, } } return nil } // /type TennisSetStat type TennisMatchStat struct { // Сколько было брейкпоинтов и сколько реализовал первый теннисист HomeBreakpoints *Breakpoints // Сколько было брейкпоинтов и сколько реализовал второй теннисист AwayBreakpoints *Breakpoints } func parseTennisMatchStat(str string) (stat TennisMatchStat, err error) { blocks, err := ParseFlashscoreEncoding(str) if err != nil { return } //buf, _ := json.MarshalIndent(blocks, "", " ") //fmt.Printf("%s\n\n", buf) var period string for _, block := range blocks { if block["SE"] != "" { if block["SE"] == "Match" { period = "match" } else { period = "" } } else { if period != "match" { continue } switch block["SG"] { case "Break Points Converted": stat.HomeBreakpoints = parseBreakpoints(block["SH"]) stat.AwayBreakpoints = parseBreakpoints(block["SI"]) } } } return } func ParseTennisSurfaceFromChampName(fullChampName string) Surface { substrings := strings.Split(fullChampName, ",") surface := substrings[len(substrings)-1] surface = strings.ToLower(strings.TrimSpace(surface)) switch surface { case "hard", "indoor hard", "indoor": return SurfaceHard case "clay", "indoor clay", "green clay", "red clay": return SurfaceClay case "grass": return SurfaceGrass case "carpet", "indoor carpet": return SurfaceCarpet default: return "" } } // ATP - SINGLES // ATP - DOUBLES // CHALLENGER MEN - SINGLES // WTA - DOUBLES // WTA - SINGLES // ITF MEN - DOUBLES // ITF WOMEN // TEAMS - WOMEN var reMen = regexp.MustCompile(`\b(atp|men)\b`) var reWomen = regexp.MustCompile(`\b(wta|wom[ea]n)\b`) func ParseTennisSexFromChampName(fullChampName string) string { fullChampName = strings.ToLower(fullChampName) if reMen.MatchString(fullChampName) { return SexMen } if reWomen.MatchString(fullChampName) { return SexWomen } return "" } func IsTennisDoublesChamp(fullChampName string) bool { fullChampName = strings.ToLower(fullChampName) return strings.Contains(fullChampName, "doubles") }