package main import ( "regexp" "strconv" "strings" ) type Departure struct { ScheduledTime string `json:"scheduled_time"` ExpectedTime string `json:"expected_time,omitempty"` Status string `json:"status"` // "On time", "Expected", "Delayed", etc. Destination string `json:"destination"` Via string `json:"via,omitempty"` Platform string `json:"platform"` Duration string `json:"duration"` Stops int `json:"stops"` Operator string `json:"operator"` DelayReason string `json:"delay_reason,omitempty"` ServiceID string `json:"service_id,omitempty"` } // ParseAriaLabel extracts departure information from the aria-label attribute func ParseAriaLabel(ariaLabel string) (*Departure, error) { departure := &Departure{} // Handle delayed trains first delayPattern := regexp.MustCompile(`^(.*?), (\d{2}:\d{2}), Expected (\d{2}:\d{2}), service for ([^,]+)(?:, via ([^,]+))?, calling at [^,]+, from platform (\d+), duration (\d+) minutes, (\d+) stops, operated by (.+)$`) if matches := delayPattern.FindStringSubmatch(ariaLabel); matches != nil { departure.DelayReason = matches[1] departure.ScheduledTime = matches[2] departure.ExpectedTime = matches[3] departure.Status = "Expected " + matches[3] departure.Destination = strings.TrimSpace(matches[4]) departure.Via = strings.TrimSpace(matches[5]) departure.Platform = matches[6] departure.Duration = matches[7] + " minutes" stops, _ := strconv.Atoi(matches[8]) departure.Stops = stops departure.Operator = strings.TrimSpace(matches[9]) return departure, nil } // Handle normal trains normalPattern := regexp.MustCompile(`^(\d{2}:\d{2}), (On time|Cancelled), service for ([^,]+)(?:, via ([^,]+))?, calling at [^,]+, from platform (\d+), duration (\d+) minutes, (\d+) stops, operated by (.+)$`) if matches := normalPattern.FindStringSubmatch(ariaLabel); matches != nil { departure.ScheduledTime = matches[1] departure.Status = matches[2] departure.Destination = strings.TrimSpace(matches[3]) departure.Via = strings.TrimSpace(matches[4]) departure.Platform = matches[5] departure.Duration = matches[6] + " minutes" stops, _ := strconv.Atoi(matches[7]) departure.Stops = stops departure.Operator = strings.TrimSpace(matches[8]) return departure, nil } return nil, nil // Unable to parse }