Regex Issue with Parsing Custom Log Formats in Go - Trouble with Optional Fields
Quick question that's been bugging me - I just started working with I'm sure I'm missing something obvious here, but I'm relatively new to this, so bear with me... I'm trying to parse log entries that have a specific custom format using regex in Go. Each log entry can optionally include a timestamp, user ID, and a message. For instance, the logs look like this: ``` 2023-10-01 12:34:56 [user123] Login successful [user456] Password change requested 2023-10-01 13:00:01 [user789] Logout ``` I want to capture the timestamp (if present), the user ID, and the message. The challenge I'm facing is that some entries do not have a timestamp, and I want to handle that gracefully. Hereโs the regex pattern Iโve attempted: ```go regex := `(?:(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s+)?\[([\w\d]+)\]\s+(.*)` ``` When I use this pattern, I can successfully match entries with timestamps, but I'm having trouble capturing the user ID and message from entries that do not have a timestamp. Specifically, when no timestamp is present, the `matches` slice only returns two elements instead of three, which leads to a runtime panic when I try to access the third element. I thought using the non-capturing group for the timestamp would resolve this, but it seems like I'm still not getting it right. Hereโs how Iโm processing the matches: ```go re := regexp.MustCompile(regex) lines := strings.Split(logs, "\n") for _, line := range lines { matches := re.FindStringSubmatch(line) if len(matches) < 3 { log.Println("No match found for line: ", line) continue } timestamp := matches[1] userID := matches[2] message := matches[3] // Process the data } ``` I'm seeing the panic when `matches` has only two elements because I'm trying to access `matches[3]` when there is no timestamp. Is there a way to modify the regex or the logic to ensure I can correctly capture both the user ID and message regardless of whether the timestamp is present? Any help would be greatly appreciated! Am I approaching this the right way? This is happening in both development and production on CentOS. The stack includes Go and several other technologies. I'm open to any suggestions.