use Modern::Perl; use Regexp::Common; my $cisco_protocol = qr { (?:ip|tcp|udp) | (?:object-group\s+[\S]+) }x; my $cisco_network = qr{ (?:host\s+[\S]+) | (?:$RE{net}{IPv4}\s+$RE{net}{IPv4}) | (?:object-group\s+[\S]+) | any }x; my $cisco_ports = qr{ (?:eq\s+\d+) | (?:range\s+\d+\s+\d+) }x; my $cisco_regex = qr{^ access-list \s+ (?[\S]+) # name \s+ extended \s+ (?(?:permit|deny)) # action \s+ (?$cisco_protocol) # protocol \s+ (?$cisco_network) # source_network \s+ (?$cisco_network) # destination_network (?:\s+(?$cisco_ports))? # ports }x; while ( my $rule = ) { chomp $rule; say "Parsing >$rule<"; if ( $rule =~ m/$cisco_regex/ ) { say "Name: $+{name}"; say "Action: $+{action}"; say "Protocol: $+{proto}"; say "Source: $+{source}"; say "Destination: $+{destination}"; say "Ports: $+{ports}" if defined $+{ports}; print "\n"; } else { say "No match\n"; } } __DATA__ access-list V420_IN extended permit object-group Symantec_Service_Group object-group Symantec_Clients Symantec_Servers access-list V420_IN extended permit object-group Symantec_Service_Group 10.148.0.0 255.254.0.0 host 10.149.16.40 access-list V420_IN extended permit object-group Symantec_Service_Group any any access-list V420_IN extended permit tcp any any range 137 139 access-list V420_IN extended permit tcp any any eq 445