herman4016 has asked for the wisdom of the Perl Monks concerning the following question:

how to extract pattern

1. .xxx ( $analog_atop_io[n] ) .or. 2. .ooo ( {$analog _atop_io[m], $analog _atop_io[m+1], $analog _atop_ +io[m+2], …} )
to $analog_atop_io[n], $analog _atop_io[m], $analog _atop_io[m+1], $an +alog _atop_io[m+2], … and then put into array @analog _atop_io
analog_atop u_analog_atop (.PAD_VDDA ( PAD_VDDA ) , , .LNA1_CURSET ( {n_IP_protect_573 , n_IP_protect_572 } ) , .CTL_CXI_XO24M ( {n662 , n447 , n449 , n2478 } ) , .CTL_SYNTH_EN ( n_IP_protect_313 ) , .CTL_CXO_XO24M ( {n2705 , n439 , n441 , n443 } ) , , .DPAD_VSS_TEMPSENSE ( DPAD_VSS_TEMPSENSE ) , .PAD_ADGPIO_2 ( PAD +_ADGPIO_2 ) ) ;

following is my code , but fail to extract ! (nothing captured)

#!/usr/bin/perl #use 5.010; use strict; use warnings; use List::MoreUtils qw(uniq); my $reS = qr{\..* \( (.*) \)}s; my $reM = qr{\..* \( \{ (.*) \} \)}s; #my $re = qr{TEXT;\s+LAYER 13[1-7];\s+TEXTTYPE 0;.*?STRING ([^;:]+)}s; open my $fh, "analog_atop_inst.v" or die $!; my @fields=(); my $i=0; { local $/ = ""; while (<$fh>) { $fields[$i] = $1 , $i++ if /$reM/; } } @fields = sort @fields; @fields = uniq (@fields); open(output_1, ">analog_atop_io".".txt") or die "can't open analog_ato +p_io\n"; foreach my $field (@fields){ $field .= "\n"; print output_1 $field ; #print $field ;

Replies are listed 'Best First'.
Re: how to extract multiple pattern into array
by roboticus (Chancellor) on Feb 02, 2015 at 08:25 UTC

    herman4016:

    It seems like you've asked several questions about parsing these files, so I'd suggest that it's time to start learning to use a proper parser for the task. Reading back on some of your previous posts, I notice that toolic already pointed you at the Verilog-Perl package.

    While searching http://cpan.org I notice that there are more projects for Verilog than I'd've guessed. I'd suggest installing the Verilog-Perl package, and reviewing the scripts it comes with (vhier, etc.) and see if any of them would make a good starting point for turning into the program you want.

    If you continue to work with Verilog files, you'll probably find that you'll start hitting the limits of what you'll be able to do reliably with regular expressions.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: how to extract multiple pattern into array
by Anonymous Monk on Feb 02, 2015 at 08:52 UTC

    roboticus and toolic are right that you should be using a real parser for such relatively complex input. Why try to re-implement a parser when it's already been done for you by someone else? :-)

    Just for completeness, how to fix your script: 1. You use local $/ = "";, which will cause the entire file to be slurped on the first iteration of the while loop, and then you only call your regex once. If you want to match once per line, remove the local $/ = "";, otherwise, you could use something like push @fields, $1 while /$reM/g; to match as many times as possible in the current string. Also, I'd change .* to being non-greedy, i.e. .*?. 2. Your regex requires a space after the opening {, but your input does not have a space there, so it will not match. I'd suggest something like \s* to match any amount of whitespace, even none.

      ... local $/ = ""; ... will cause the entire file to be slurped ...

      From  perldoc -v "$/" (see also perlvar):

      HANDLE->input_record_separator( EXPR ) $INPUT_RECORD_SEPARATOR $RS $/ The input record separator ... treating empty lines as a terminator if set to the null string + ... You may set it to ... "undef" to read through the end of file. ...
      The idiomatic Perl statement would be something like
          my $entire_data = do { local $/;  <$filehandle>; };
      (if you don't use something like File::Slurp).


      Give a man a fish:  <%-(-(-(-<

        Oops, thanks :-)