How can I merge these 2 regex's to a single regex which captures all available parts depending on the string structure ( the last 3 fields in $s are optional and should be captured if they exists)? Using (?= ... ) I could not get a working solution.
$s='1.2.3.4 - egon [10/Dec/2007:21:07:20 +0100] "GET /x.htm HTTP/1.1" 401 488';
$re = qr/\A
(\d+)\.(\d+)\.(\d+)\.(\d+)
[ ] (\S+)
[ ] (\S+)
[ ]+ \[(\d+)\/(\S+)\/(\d+):(\d+):(\d+):(\d+) [ ] (\S+)\]
[ ] "(\S+) [ ] (.*?) [ ] (\S+)"
[ ] (\S+)
[ ] (\S+)
\Z/x;
print "[".join('],[',$s =~ $re)."]\n\n";
$s='1.2.3.4 - - [13/Jun/2007:01:37:44 +0200] "GET /x.htm HTTP/1.0" 404 283 "-" "Mozilla/5.0..." "-"';
$re = qr/\A
(\d+)\.(\d+)\.(\d+)\.(\d+)
[ ] (\S+)
[ ] (\S+)
[ ]+ \[(\d+)\/(\S+)\/(\d+):(\d+):(\d+):(\d+) [ ] (\S+)\]
[ ] "(\S+) [ ] (.*?) [ ] (\S+)"
[ ] (\S+)
[ ] (\S+) [ ] "(.*?)" [ ] "(.*?)" [ ] "(.*?)"
\Z
/x;
print "[".join('],[',$s =~ $re)."]\n\n";
my $tokenize = qr/\A (\d+)\.(\d+)\.(\d+)\.(\d+) [ ] (\S+) (?: [ ] (\S*))? (?: [ ] (\S*))? [ ] \[(\d+)\/(\S+)\/(\d+):(\d+):(\d+):(\d+) [ ] (\S+)\] [ ] "(?:(\S+) [ ])? (.*?) (?:[ ] (\S+))?" [ ] (\S+) [ ] (\S+) (?: [ ] "(.*?)" [ ] "(.*?)" [ ] "(.*?)" )? \Z/x;