in reply to multiple matches in regex
Here is your question, rephrased (and trimmed down) as best I could decipher. Please clarify if I misunderstood, because this question is what I am answering below.
my @data = ( 'Line1 <error 1 1 <foo> <bar>> <three 1 1 <baz> <qux>> <fixv 1 1 qib + qeg>', 'Line2 error 1 1 <foo> <bar> <three 1 1 <baz> <qux>> <fixv 1 1 qib q +eg>', ); # The single match on Line2 is correct, # but I am only getting one match from Line1. # When I work the pattern by hand, # I see that it should match twice on Line2. # How can I get the second match? foreach my $test (@data) { if ($test =~ /(<[a-z]{4,5}\s\d\s\d\s<[^>]+?>\s<[^>]+?>>)/gx ) { print "Found '$1' in line '$test'\n"; } }
When you want to capture separate instances of the match multiple times in the same line you use the /g modifier, and either:
Working, tested code:
use strict; use warnings; # Set this to 0 or 1; # the output will be exactly the same either way. my $use_scalar_method = 1; # I added the first "open inner brace", # so that the indentation would balance. my $pattern = qr/ \{ # open outer brace [a-z]{4,5} # 4 or 5 lowercase letters \s # \d # single digit \s # \d # single digit \s # \{ # open inner brace [^}]+? # everything up to the close brace \} # close inner brace \s # \{ # open inner brace [^}]+? # everything up to the close brace \} # close inner brace \} # close outer brace /x; my @data = ( 'DataLine1 {error 1 1 {^E 0-20-9:0-50-9:0-50-9.*$} {^E 0-20-9:0-50-9 +:0-50-9.*$}} {three 1 1 {^.*35=A.*$|^.*35=5.*$} {^.*35=A.*$|^.*35=5.* +$}} {fixv 1 1 ^.*VFIXFxProxy.*Disconnected ^.*VFIXFxProxy.*Disconnect +ed}', 'DataLine2 error 1 1 {^E 0-20-9:0-50-9:0-50-9.*$} {^E 0-20-9:0-50-9: +0-50-9.*$} {three 1 1 {^.*35=A.*$|^.*35=5.*$} {^.*35=A.*$|^.*35=5.*$} +} {fixv 1 1 ^.*VFIXFxProxy.*Disconnected ^.*VFIXFxProxy.*Disconnected +}', 'DataLine3 error 1 1 {^E 0-20-9:0-50-9:0-50-9.*$} {^E 0-20-9:0-50-9: +0-50-9.*$} {twentythreeistoobig 1 1 {^.*35=A.*$|^.*35=5.*$} {^.*35=A. +*$|^.*35=5.*$}} {fixv 1 1 ^.*VFIXFxProxy.*Disconnected ^.*VFIXFxProxy +.*Disconnected}', ); my $line_number = 0; foreach my $test (@data) { $line_number++; print "\nLine: $line_number\n"; if ($use_scalar_method) { my $match_number = 0; # Scalar context: # You can get the matches one-at-a-time this way. while ( $test =~ /($pattern)/g ) { $match_number++; print "Match $match_number: $1\n"; } print "No matches.\n" unless $match_number; } else { # List context: # You can get all the matches at once this way. my @matches = ($test =~ /($pattern)/g) or print "No matches.\n" and next; my $match_number = 0; foreach my $match (@matches) { $match_number++; print "Match $match_number: $match\n"; } } }
|
|---|