use warnings; use strict; use Regexp::Grammars; use Data::Dumper; my $data = join "", ; my $matcher = qr{ ^ <[Commands]>+ $ module \s \s ; \n endmodule \n? ( ||| );\n nand \s \s input \s output \s wire \s [\p{L}\d_]+ N\d+ <[Node]>+ % , \(\) }; if ( $data =~ $matcher ) { print Dumper \%/; #/ } else { print "NO MATCH"; } __DATA__ module circuit_17 (N1,N2,N3,N6,N7,N22,N23); input N1,N2,N3,N6,N7; output N22,N23; wire N10,N11,N16,N19; nand nand2_1 (N10,N1,N3); nand nand2_2 (N11,N3,N6); nand nand2_3 (N16,N11,N2); nand nand2_4 (N19,N11,N7); nand nand2_5 (N22,N10,N16); nand nand2_6 (N23,N16,N19); endmodule #### $VAR1 = { 'Module' => { 'BracketedNodes' => { 'Nodes' => { 'Node' => [ 'N1', 'N2', 'N3', 'N6', 'N7', 'N22', 'N23' ] } }, 'Name' => 'circuit_17' }, 'Commands' => [ { 'Input' => { 'Nodes' => { 'Node' => [ 'N1', 'N2', 'N3', 'N6', 'N7' ] } } }, { 'Output' => { 'Nodes' => { 'Node' => [ 'N22', 'N23' ] } } }, { 'Wire' => { 'Nodes' => { 'Node' => [ 'N10', 'N11', 'N16', 'N19' ] } } }, { 'Nand' => { 'BracketedNodes' => { 'Nodes' => { 'Node' => [ 'N10', 'N1', 'N3' ] } }, 'Name' => 'nand2_1' } }, { 'Nand' => { 'Name' => 'nand2_2', 'BracketedNodes' => { 'Nodes' => { 'Node' => [ 'N11', 'N3', 'N6' ] } } } }, { 'Nand' => { 'Name' => 'nand2_3', 'BracketedNodes' => { 'Nodes' => { 'Node' => [ 'N16', 'N11', 'N2' ] } } } }, { 'Nand' => { 'Name' => 'nand2_4', 'BracketedNodes' => { 'Nodes' => { 'Node' => [ 'N19', 'N11', 'N7' ] } } } }, { 'Nand' => { 'BracketedNodes' => { 'Nodes' => { 'Node' => [ 'N22', 'N10', 'N16' ] } }, 'Name' => 'nand2_5' } }, { 'Nand' => { 'Name' => 'nand2_6', 'BracketedNodes' => { 'Nodes' => { 'Node' => [ 'N23', 'N16', 'N19' ] } } } } ], 'EndModule' => 'endmodule' };