Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Special Variable Pattern Match whilst reading input from a file

by Withnail (Novice)
on Mar 29, 2003 at 19:42 UTC ( [id://246638]=perlquestion: print w/replies, xml ) Need Help??

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

Please forgive me - I need help! I'm a little rusty and I'm wondering if there's a better way of achieving the result I'm after.

I need to extract a string from a line within file. I will then use this string as a variable within my procedure.

The line always starts with the string "frz = ", and the value I need to extract comes after this.

Here's what I've got so far:

open (CONFIG_FILE, "$config_file") || die while (<CONFIG_FILE>) { if (($foo) = /^frz\s+=\s+(\w+)\;/) { $bar = $foo; } } print "$bar\n"; close (CONFIG_FILE) || die

So, I end up with $bar as the variable I can use.

My question is "Do I need $foo as an intermediate variable?" Is there a more 'elegant way of extracting the information I want?

Replies are listed 'Best First'.
Re: Special Variable Pattern Match whilst reading input from a file
by zby (Vicar) on Mar 29, 2003 at 19:49 UTC
    while (<CONFIG_FILE>) { if(/^frz\s+=\s+(\w+)\;/) $bar = $1; } } print "$bar\n";
    You can use the $n variables.
Re: Special Variable Pattern Match whilst reading input from a file
by Enlil (Parson) on Mar 29, 2003 at 20:04 UTC
    A couple of things.
    1. /^frz\s+=\s+(\w+)\;/ will not match a line starting with "frz=" as there is a mandatory whitespace after the z in your regular expression (you were probably looking for \s* so it will match both lines starting with "frz=" or "frz  =" (you might want to change the other \s+ to \s* depending on what the line might look like after the "=".
    2. One way to skip the intermediate variable would be:
    open (CONFIG_FILE,"$config_file") or die "Can't open $config_file"; my $bar; while(<CONFIG_FILE>){ next unless /^frz\s*=\s*(\w+)\;/; $bar = $1; } print $bar,$/; close(CONFIG_FILE) or die;

    -enlil

Re: Special Variable Pattern Match whilst reading input from a file
by nothingmuch (Priest) on Mar 29, 2003 at 19:53 UTC
    open (CONFIG_FILE, "$config_file") || die LINE: while (<CONFIG_FILE>) { if ( /^frz\s+=\s+(\w+)\;/ ) { $bar = $1; } } print "$bar\n"; close (CONFIG_FILE) || die;
    I'd like to note that currently bar will simply be set to the last matching line's value. Is that what you want? because you can also add a last LINE; expression, under $bar = $1, to tell perl you're done reading. You needn't go through the whole file, only up to the point where the line is.

    -nuffin
    zz zZ Z Z #!perl
Re: Special Variable Pattern Match whilst reading input from a file
by dakkar (Hermit) on Mar 29, 2003 at 19:53 UTC

    Parenthesised matches always end up in the match variables $1, $2, ..., so you could write:

    while (<CONFIG_FILE>) { if (/^frz\s+=\s+(\w+);/) {$bar=$1} }

    If you have more than one pair of parenthesis, $1 will refer to the match of the first pair, $2 to the second and so on. The pairs are ordered from left to right, counting their opening parenthesis, so:

    "abc123def"=~/([a-z]+(\d+)(.*))/; print "first: $1\nsecond: $2\nthird: $3\n";
    would print:
    first: abc123def
    second: 123
    third: def
    

    -- 
            dakkar - Mobilis in mobile
    
Re: Special Variable Pattern Match whilst reading input from a file
by DarknessX (Scribe) on Mar 29, 2003 at 19:53 UTC
    try this:
    open FILE, "$file" or die "$!"; while (<FILE>){ m/^frz\s=\s(\w+)\;/; print $1; } close FILE;
    See, the (\w+) will take whatever is matched by \w+ and store it in $1, perl's magic match variable. that way you eliminate the need for $foo and $bar altogether.
    -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GPA/P/S d+ s++:+ a--- C++ UL++ P++>++++ L++ E W++ N o? K? w-- !O M- V? + PS++ PE- Y PGP- t 5- X+ R* tv-- b++ !DI D---(+) G e- h-- r++ y+++++> ++ ------END GEEK CODE BLOCK-----
Re: Special Variable Pattern Match whilst reading input from a file
by Aragorn (Curate) on Mar 29, 2003 at 20:23 UTC
    And a slightly different solution:
    while (<CONFIG>) { $bar = $1 if /^frz\s*=\s*(\w+);/; }

    Arjen

    Update:Oops, forgot the (apparently) mandatory semicolon.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://246638]
Approved by nothingmuch
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-04-19 09:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found