use warnings; use strict; while () { chomp; if (! m{ /(\d+) # Get first bunch of digits following a / .*? Date\sTime\s # match date time string ( (?: (?! \s\d+/). )+ ) # Everything up to the space before \d+/ [^/]+ / # Throw away the unwanted digits preceeding / (\d+) # Grab last number (.*) # Grab tail for subsequent checking }x # allow most white space and comments ) { print "No match: $_\n"; next; } my ($first, $datetime, $last, $tail) = ($1, $2, $3, $4); if ($tail =~ /(\) | \.sta \)?) $/x) { print "Skipping $_\n"; next; } print "Extracted $first, $datetime, $last\n"; } __DATA__ 12345645/883700892.log Date Time 4 kkdjkdkd 889298383/883729083.dat 12345645/883700892.log Date Time 4 kkdjkdkd 889298383/883729083.sta (12345645/883700892.log Date Time 4 kkdjkdkd 889298383/883729083.dat) (12345645/883700892.log Date Time 4 kkdjkdkd 889298383/883729083.sta) Completely badly formed #### Extracted 883700892, 4 kkdjkdkd, 883729083 Skipping 12345645/883700892.log Date Time 4 kkdjkdkd 889298383/883729083.sta Skipping (12345645/883700892.log Date Time 4 kkdjkdkd 889298383/883729083.dat) Skipping (12345645/883700892.log Date Time 4 kkdjkdkd 889298383/883729083.sta) No match: Completely badly formed