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

I have some variables declared like
$var = ".declare book_num a13"; $var = ".declare cube_no 9999999.999";
and I want to extract only the variable names i.e.(book_num,cube_no) in a another variable and I am using regex for this..but its not working ..can u please help me out..My regex is
$var =~ s/^(\.\w+\s+)(\w+)(\s+.)/$2/g;
but its not working...

Replies are listed 'Best First'.
Re: Extract the variable
by ForgotPasswordAgain (Vicar) on Jun 25, 2007 at 12:00 UTC

    I'm guessing you're trying to use $var. You could either not use s///:

    $var =~ /^\.\w+\s+(\w+)\s+./; $var = $1;

    or finish off what you had there:

    $var =~ s/^(\.\w+\s+)(\w+)(\s+.+)/$2/;

    (note the + near the end, which allows more than one character to match; the result of the substitution in $var is what's left over after you did the substituting)

      Now my file contains these data
      .rem ***************************************************************** +***** .rem * + * .rem * deb123.rpt + * .rem ***************************************************************** +***** .rem .rem ------------------------ book_tab variables --------------------- .rem .declare book_no a14 .declare l_code a10 .declare l_book a12 .declare book_date a13
      and I need to read this file line by line the file name is deb123.rpt and my code is
      use IO::File; my $fh = IO::File->new(); die "File $ARGV[0] is there in the specified location but is of Zero b +ytes" if (-z $ARGV[0]); $ARGV[0] .= ".rpt"; $fh->open($ARGV[0], "r"); local($/); #my $data = $fh->getline; #$fh->close; while(defined($data = $fh->getline)){ if($data =~ /^\.r/){ print "This is a comment $data\n"; } if($data =~ /^\.dec/){ print "This is declared variable $data\n"; } } $fh->close;
      but its not giving any output and even its not printing the data at particular line in the file also... Please help me out for the code
        Your use of my leads me to hope that you are putting use strict; and use warnings; at the top of your scripts. It is also a good idea to indent your code (my preference is four spaces) to give a visual indication to control flow.

        I'm not sure why you are using IO::File when three-argument open anf lexical filehandle will serve as well. I have used your data but have added a bogus line to demonstrate how to handle lines that don't fit your expectations. I use a regex capture to get the variable name (captured in $1) and print it out; obviously, you can assign it to a variable for later use. Once you know what a line is and have dealt with it, use next to get the next line rather than testing further. Here is the input file

        the code

        use strict; use warnings; my $inFile = q{spw623147.txt}; open my $inFH, q{<}, $inFile or die qq{open: $inFile: $!\n}; while ( <$inFH> ) { if ( m{\A\.rem} ) { print qq{ Comment Line: $_}; next; } if ( m{\A\.declare\s+(\S+)} ) { print qq{ Data Line: $_}; print qq{ Variable is: $1\n}; next; } print qq{Not recognised: $_}; } close $inFH or die qq{close: $inFile: $!\n};

        and the output

        Comment Line: .rem ************************************************* +********************* Comment Line: .rem * + * Comment Line: .rem * deb123.rpt + * Comment Line: .rem ************************************************* +********************* Comment Line: .rem Comment Line: .rem ------------------------ book_tab variables ----- +---------------- Comment Line: .rem Data Line: .declare book_no a14 Variable is: book_no Data Line: .declare l_code a10 Variable is: l_code Not recognised: .burble nonsense directive here Data Line: .declare l_book a12 Variable is: l_book Data Line: .declare book_date a13 Variable is: book_date

        I hope thisis of use.

        Cheers,

        JohnGG

        Update: Fixed typo

        A reply falls below the community's threshold of quality. You may see it by logging in.
      $var =~ /^\.\w+\s+(\w+)\s+./; $var = $1;

      While this is the obvious and most reasonable suggestion, given the apparent level of (in-)expertise of the OP, it should be worth reminding him of always checking whether the match actually succeeded.

      Thanx dear!!! Its working now!!! Can I use substr instead of regex?
        &ot

        Presuming ".declare " is a fixed prefix and the variable name is always followed by a real space character (i.e. you're not worried that there's a TAB instead) then yes you could use substr starting at offset 10 after using index (also starting at offset 10) to find where the variable name ends.

Re: Extract the variable
by jagh (Monk) on Jun 25, 2007 at 12:01 UTC

    It's not working because you're only replacing the first part, not the entire thing. Try this:

    $var = ".declare book_num a13"; $var =~ s/^\.\w+\s+(\w+).*$/$1/g;

    Or, forget the substitution:

    $var = ".declare book_num a13"; $var =~ /^\.\w+\s+(\w+)/; print $1;

    (Make sure to check that there /was/ a match, of course). If you haven't already, check out the relevant perldocs as well, such as perlretut.

    Update: Whoops, ForgotPasswordAgain beat me to it.
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Extract the variable
by naikonta (Curate) on Jun 26, 2007 at 14:37 UTC
    In this particular case, I prefer to use split as demonstrated by EvanK. However, if you insisted on regex, specially for irregular patterns (e.g. not always ".declare"), than I would use simpler regex:
    $ perl -wle '$_=shift; /\S+\s+(\S+)/ and print $1' ".declare cube_no + 9999999.999" cube_no
    But still, on this "regular irregular patterns", splitting on spaces (or other possible delimiters) still wins over regex in my toolbag.
    $ perl -wle '$_=shift; print +(split)[1]' ".declare cube_no 999 +9999.999" cube_no

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!