package parser import ( "regexp" "strconv" "strings" "time" ) type Telegram struct { Text string Complete bool Parsed bool Fields []string Sequence int Type string FlopValue []string FlightNumber string Plane string Aircraft string RegisterNumber string Departure string DepartureTime time.Time Destination string DestinationTime time.Time DateOfFlight time.Time ParseErrors []error } const ( Start = "ZCZC" End = "NNNN" TmqRegex = `TMQ(?P\d{4})` ) //Parse func Parse(text string) (*Telegram, error) { var telegram = &Telegram{Text: text} telegram.Complete = isStartAndEnd(text) telegram.Fields = strings.Split(strings.Replace(text, "\r\n", "\n", -1), "\n") telegram.Fields = clean(telegram.Fields) seq := getFields(TmqRegex, telegram.Fields[0]) telegram.Sequence, _ = strconv.Atoi(seq["tmq"]) if isPln(*telegram) { telegram.Type = TypePLN } else if flopValues := getFields(FlopRegex, telegram.Text); len(flopValues) > 0 { telegram.Type = flopValues["type"] data := flopRegex.FindString(telegram.Text) switch telegram.Type { case TypeArrival, TypeDeparture: parseArrOrDep(telegram, data) case TypeFlightPlan: parseFlightPlan(telegram, data) case TypeDelay: parseDelay(telegram, data) } } return telegram, nil } func isStartAndEnd(s string) bool { text := strings.TrimSpace(s) return strings.HasPrefix(text, Start) && strings.HasSuffix(text, End) } func clean(fields []string) []string { var values []string for _, s := range fields { values = append(values, strings.TrimSpace(s)) } return values[:len(values)-1] } func getFields(regEx string, field string) (fields map[string]string) { var compRegEx = regexp.MustCompile(regEx) match := compRegEx.FindStringSubmatch(field) fields = make(map[string]string) for i, name := range compRegEx.SubexpNames() { if i > 0 && i <= len(match) { fields[name] = match[i] } } return } func getSplitValues(s string) []string { // get rid of () s = strings.TrimSpace(s) s = s[1 : len(s)-1] return strings.Split(s, "-") } func parseFlight(s string) (flightNumber string, registerNumber string) { if l := strings.Index(s, "/"); l > 0 { return s[0:l], s[l+1:] } return s, "" } func parseAirportAndTime(s string) (airport string, arrivalTime time.Time) { fields := getFields(DestinationRegex, s) arrivalTime, _ = time.Parse("1504", fields["time"]) return fields["dest"], arrivalTime } func parseDof(text string) time.Time { value := getFields(DofValueRex, text) dof, _ := time.Parse("060102", value[KeyTime]) return dof } func getOtherRegexWithName(name string) string { return strings.ReplaceAll(OtherRegex, "NAME", name) }