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

Following are contents of tt.txt,

 .dout_sar ( dout_sar ) , .dcoc_status ( dcoc_status ) ,     .sdm_yout_i ( {sdm_yout_i[1] , n145 } ) , .sdm_yout_q ( sdm_yout_q ) ,

I want to grep :

 .sdm_yout_i ( {sdm_yout_i[1] , n145 } )

Following is my code , but the result is nothing , please help !!

#!/usr/bin/perl use 5.010; use strict; use warnings; my $port_name = 'sdm_yout_i[1]'; open my $fh, "tt.txt" or die $!; while (<$fh>) { if ($_ =~ /\.([0-9a-z_]*?) \(.*?${port_name} .*?,/) { print '$port_name = ' ; say $port_name; print 'cell name = ' ; say $1; } }

Replies are listed 'Best First'.
Re: Regular Expressions with varialbe with "[]" (Verilog)
by toolic (Bishop) on Mar 10, 2015 at 14:06 UTC
    quotemeta:
    use 5.010; use warnings; use strict; my $port_name = quotemeta 'sdm_yout_i[1]'; while (<DATA>) { if (/\.([0-9a-z_]*?) \(.*?${port_name} .*?,/ ) { print '$port_name = '; say $port_name; print 'cell name = '; say $1; } } __DATA__ .dout_sar ( dout_sar ) , .dcoc_status ( dcoc_status ) , .sdm_yout +_i ( {sdm_yout_i[1] , n145 } ) , .sdm_yout_q ( sdm_yout_q ) ,

    Outputs:

    $port_name = sdm_yout_i\[1\] cell name = dout_sar

    If you plan on parsing Verilog code, consider Verilog-Perl

      Thanks everybody about your kindly reply, following is my code according your replies, and the output which I want :

      #!/usr/bin/perl use 5.010; use strict; use warnings; my $port_name = 'sdm_yout_i[1]'; open my $fh, "tt.txt" or die $!; while (<$fh>) { if (/\.([0-9a-z_]*?) \( \{.*?\Q$port_name\E .*?,/) { print '$port_name = ' ; say $port_name; print '$cell name = ' ; say $1; } }

      Outputs:

      $port_name = sdm_yout_i[1] $cell name = sdm_yout_i
Re: Regular Expressions with varialbe with "[]"
by choroba (Cardinal) on Mar 10, 2015 at 14:04 UTC
    In regular expressions, [1] is a character class matching the character 1. To prevent the string from interpretation, use \Q:
    if (/\.([0-9a-z_]*?) \(.*?\Q$port_name\E .*?,/) {
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Regular Expressions with varialbe with "[]"
by hdb (Monsignor) on Mar 10, 2015 at 14:04 UTC
Re: Regular Expressions with varialbe with "[]"
by Anonymous Monk on Mar 10, 2015 at 14:12 UTC

    The characters [] are special in regexes, and you need to escape them with \Q...\E aka quotemeta. If I replace ${port_name} with \Q$port_name\E, I get the output "$port_name = sdm_yout_i[1]  cell name = dout_sar". If you want the "cell name" to be "sdm_yout_i", you need to further restrict your regex and replace the .*? just before $port_name with something like \W*.

    But this still all feels a bit like a hack. You've been advised to use real Verilog parsers like Verilog::VCD and Verilog-Perl in four separate threads now (out of five total). Perhaps it's about time you looked into getting those installed?

Re: Regular Expressions with varialbe with "[]"
by SuicideJunkie (Vicar) on Mar 10, 2015 at 15:30 UTC

    You need to escape the ['s and ]'s.  qr"..." and \Q and \E are useful for that. Consider:

    my $haystack = 'lets test[1] this thing $string'; my @tests = ('test[1]', '\Etest[1]\Q', 'test\[1\]'); @tests = map {$_, qr"\Q$_\E"} @tests; print "Check $_:" . ($haystack =~ /($_)/ ? "got $1\n" : "no match\n") +for @tests;
    which results in:
    Check test[1]:no match Check (?^:test\[1\]):got test[1] Check \Etest[1]\Q:no match Check (?^:\\Etest\[1\]\\Q):no match Check test\[1\]:got test[1] Check (?^:test\\\[1\\\]):no match
Re: Regular Expressions with varialbe with "[]"
by pme (Monsignor) on Mar 10, 2015 at 14:25 UTC
    hi herman4016

    I modified the regexp a little. You don't need memory braces because variable $& contains the match and '+?' turns the regexp non-greedy.

    use strict; use warnings; use 5.010; my $port_name = 'sdm_yout_i[1]'; $port_name =~ s/\[|\]/\\$&/g; # escaping &#91; and &#93; while (<DATA>) { if ( /\.[0-9a-z_]+ \( {${port_name}.+?\)/ ) { print '$port_name = ' ; say $port_name; print 'cell name = ' ; say $&; } } __DATA__ .dout_sar ( dout_sar ) , .dcoc_status ( dcoc_status ) , .sdm_yout_i ( +{sdm_yout_i[1] , n145 } ) , .sdm_yout_q ( sdm_yout_q )

      Thanks pme another method to solve , following is my code and what I want :

      #!/usr/bin/perl use 5.010; use strict; use warnings; my $port_name = 'sdm_yout_i[1]'; $port_name =~ s/\[|\]/\\$&/g; # escaping &#91; and &#93; open my $fh, "tt.txt" or die $!; while (<$fh>) { if ( /\.([0-9a-z_]+?) \( \{.*?${port_name} .*?,/ ) { print '$port_name = ' ; say $port_name; print '$cell name = ' ; say $1; } }

      Output :

      $port_name = sdm_yout_i\[1\] $cell name = sdm_yout_i