Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Store and match

by Anonymous Monk
on Aug 11, 2009 at 06:14 UTC ( #787493=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

#!/usr/bin/perl while($_=<DATA>){ $x =~ /^\[Note\](\w+)/; print $x; } __DATA__ [Note]note_values,notes_values2 [Book]novels,magazines
How to store the value of only Note. i.e, How to store the value "note_values,notes_values2" in a variable and from that grep the value notes_values2.

Replies are listed 'Best First'.
Re: Store and match
by prasadbabu (Prior) on Aug 11, 2009 at 06:26 UTC

    The mistake you have done is you have not stored the current line in variable $x. Also \w+ will match only 'note_values' and not the remaining string 'note_values,notes_values2 ' as it contains ',' in between.

    The below code will meet your requirement. Also refer perlre to learn how to store the matched value in variables.

    while($x=<DATA>){ if ($x =~ /^\[Note\](.+)$/){ $var = $1; #store in a variable print $var; } }


      #!/usr/bin/perl while($x=<DATA>){ if ($x =~ /^\[Note\](.+)$/){ $var = $1; #store in a variable print $var; } } __DATA__ [Note] note_values,notes_values2 [Book] novels,magazines [Note] note_values,notes_values3
      Hi, if the values are as above, then how to print the values of Note. If the values of Note has "note_values", then how to count the number of occurence

        I am not clear with your inputs because in your previous node you gave [Note] in same line and now in two lines. Any how the below code will work for your above input. It will also match note_values if more than one present in a single line.

        use strict; use warnings; my $prev = 0; my $total = 0; while(my $x = <DATA>){ $prev = 1 if ($x =~ /^\[Note\]$/); my $count = 0; if (($x =~ /note_values/) && $prev){ $count = $x =~ s/(note_values)/$1/g; #if more than one note_va +lues present in a line $prev = 0; } $total = $total + $count; } print "Number of occurence: $total";


Re: Store and match
by vinoth.ree (Monsignor) on Aug 11, 2009 at 07:26 UTC

    As prasadbabu given correct answer I believe.

    As of my understand you want the last potion from the line which begins with Note. I also done this with split function.

    use strict; use warnings; my $x; while($x=<DATA>){ chomp($x); if ($x =~ /^\[Note\]/){ my $find=(split(/\,/,$x))[-1] ; print "$find\n"; + + } } __DATA__ [Note]note_values,notes_values2 [Book]novels,magazines [Note]note_values,notes_values56
Re: Store and match
by cdarke (Prior) on Aug 11, 2009 at 07:50 UTC
    Your data line is read into $_, but you are using $x for the match. To get separate the parts:
    # $_ is the default buffer and pattern space while(<DATA>){ /^(\[\w+\])(.+)/; my $prefix = $1; my $values = $2; print "prefix:$prefix values:$values\n"; }
    Not sure if you require the square brackets in your result or not. Note that \w does not include a comma, and that there are, of course, many other ways to do it.
Re: Store and match
by Bloodnok (Vicar) on Aug 11, 2009 at 13:18 UTC
    In general, you might like to have a look at the format, also the assignment in while ($_=<DATA>)... is superfluous - while (<DATA>)... does exactly the same thing.

    As to the exact problem, using strictures would have given you a clue to solving the problem since, assuming you rewrite $x =~ /^\[Note\](\w+)/; to my $x =~ /^\[Note\](\w+)/; (to remove the undeclared variable error that would otherwise ensue), you would have seen a use of uninitialised value in pattern match... error, the solution to which is (my $x = $_) =~ /^\[Note\](\w+)/;.

    Having done all that, you can then go on to solve the problem of extracting the value from the field - maybe along the lines of $x =~ s/[^,]*,//;, so the final code should, IMO, look like:

    <p>#!/usr/bin/perl use warnings; use strict; while (<DATA>){ (my $x = $_) =~ /^\[Note\](\w+)/; $x =~ s/[^,]*,//; print $x; } __DATA__ [Note]note_values,notes_values2 [Book]novels,magazines
    Which generates:
    $ perl notes_values2 magazines $
    As required. It then becomes a trivial exercise to ignore lines of no interest...

    A user level that continues to overstate my experience :-))
Re: Store and match
by Utilitarian (Vicar) on Aug 11, 2009 at 07:56 UTC
    #!/usr/bin/perl use strict; use warnings; while($_=<DATA>){ if (/^\[Note\]\w+,(\w+)/){ my $x =$1; print "$x\n"; } } __DATA__ [Note]note_values,notes_values2 [Book]novels,magazines
    A couple of comments:
    • use strict and use warnings even on a little script they will often catch a simple error that your eyes will gloss over "seeing what I meant to write"
    • $x=~/^\[Note\](\w+)/; tries to match the regex in $x
    • I think it does what you're looking for, if I read your question correctly
Re: Store and match
by bichonfrise74 (Vicar) on Aug 11, 2009 at 16:54 UTC
    How about this?
    #!/usr/bin/perl use strict; while(<DATA>){ my ($x) = $_ =~ /^\[Note\](.*)/; print $x if ( defined( $x ) ); } __DATA__ [Note]note_values,notes_values2 [Book]novels,magazines
Re: Store and match
by Marshall (Abbot) on Aug 11, 2009 at 22:31 UTC
    Your data looks a lot like a ".ini" or "config" file. I suggest looking at something like use Config::INI::Reader, there are other config readers.

    Update: I don't think that I was clear at all. Sorry. The idea is to put the data into a standard file format and use one of the Perl modules to parse it for you. I've used some of these .ini or .config file parsers and they work very well. I think it is something to be seriously considered. A file could look like this:

    [Note] note_value1 notes_value2 or [Note] values = value1, value2 [Book] novels = 211 magazines = "Scientific American", "Economist"

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://787493]
Approved by prasadbabu
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2017-04-30 18:12 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (542 votes). Check out past polls.