use v5.10; my $acl_rx = qr{ (?&acl) # match one of these # according to these "regex sub" definitions: (?(DEFINE) (? access_list (?&interface_name) (?&action) (?&protocol) (?&source) (?&destination) (?&port) ) (? permit | deny ) (? tcp | udp | ip | object-group (?&object_group_name) ) (? object-group (?&object_group_name) | host (?&host_address) | (?&network_address) (?&net_mask) ) (? object-group (?&object_group_name) | host (?&host_address) | (?&network_address) (?&net_mask) ) (? eq (?&port_number) | range (?&low_port) (?&high_port) | ) (? (?&chunk) ) (? (?&chunk) ) (? (?&chunk) ) (? (?&chunk) ) (? (?&chunk) ) (? (?&chunk) ) (? (?&chunk) ) (? (?&chunk) ) (? (?&ws) \S+ (?&ws) ) (? \s* ) ) }x; #### use Data::Dump; my $acl_grammar = do { use Regexp::Grammars; qr{ # In case you need it, uncomment this line: # # Match this... # According to these definitions: access-list extended permit | deny tcp | udp | ip | object-group object-group object-group | host | object-group | host | eq | range |
any | | \d+ <.octet> ( <.dot> <.octet> ){3} \( [^()]* \) \w+ \d{0,3} \. <.capword> ** _ \p{Lu} \p{Alnum}+ }x; }; while (my $input = ) { if ($input =~ $acl_grammar) { say "MATCHED"; dd \%/; # parse tree of a successful match # appears in the %/ variable } else { warn "CAN'T MATCH: $input"; } } __END__ access-list V420_IN extended permit object-group Symantec_Service_Group object-group Symantec_Clients Symantec_Servers (all 3 object groups) access-list V421_IN extended permit object-group Symantec_Service_Group 10.148.0.0 255.254.0.0 host 10.149.16.40 (One service group and two network addresses) access-list V422_IN extended permit object-group Symantec_Service_Group any any (Source & Destination any) access-list V423_IN extended permit tcp any any range 137 139 (with a range of TCP ports) access-list V424_IN extended permit tcp any any eq 445 (with a single service port) #### MATCHED { "" => "access-list V420_IN extended permit object-group Symantec_Service_Group object-group Symantec_Clients Symantec_Servers (all 3 object groups)", "acl" => { "" => "access-list V420_IN extended permit object-group Symantec_Service_Group object-group Symantec_Clients Symantec_Servers (all 3 object groups)", "action" => "permit", "comment" => "(all 3 object groups)", "destination" => { "" => "Clients Symantec_Servers", "net_mask" => { "" => "Symantec_Servers", "address" => { "" => "Symantec_Servers", "name" => "Symantec_Servers" }, }, "network_address" => { "" => "Clients", "address" => { "" => "Clients", "name" => "Clients" }, }, }, "interface_name" => { "" => "V420_IN", "name" => "V420_IN" }, "port" => "", "protocol" => { "" => "object-group Symantec_Service_Group", "object_group_name" => { "" => "Symantec_Service_Group", "chunk" => "Symantec_Service_Group" }, }, "source" => { "" => "object-group Symantec_", "object_group_name" => { "" => "Symantec_", "chunk" => "Symantec_" }, }, }, } MATCHED { "" => "access-list V421_IN extended permit object-group Symantec_Service_Group 10.148.0.0 255.254.0.0 host 10.149.16.40 (One service group and two network addresses)", "acl" => { "" => "access-list V421_IN extended permit object-group Symantec_Service_Group 10.148.0.0 255.254.0.0 host 10.149.16.40 (One service group and two network addresses)", "action" => "permit", "comment" => "(One service group and two network addresses)", "destination" => { "" => "host 10.149.16.40", "host_address" => { "" => "10.149.16.40", "address" => { "" => "10.149.16.40", "dotted_quad" => "10.149.16.40" }, }, }, "interface_name" => { "" => "V421_IN", "name" => "V421_IN" }, "port" => "", "protocol" => { "" => "object-group Symantec_Service_Group", "object_group_name" => { "" => "Symantec_Service_Group", "chunk" => "Symantec_Service_Group" }, }, "source" => { "" => "10.148.0.0 255.254.0.0", "net_mask" => { "" => "255.254.0.0", "address" => { "" => "255.254.0.0", "dotted_quad" => "255.254.0.0" }, }, "network_address" => { "" => "10.148.0.0", "address" => { "" => "10.148.0.0", "dotted_quad" => "10.148.0.0" }, }, }, }, } CAN'T MATCH: access-list V422_IN extended permit object-group Symantec_Service_Group any any (Source & Destination any) CAN'T MATCH: access-list V423_IN extended permit tcp any any range 137 139 (with a range of TCP ports) CAN'T MATCH: access-list V424_IN extended permit tcp any any eq 445 (with a single service port)