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

Hi, I am reading a configuration file in the form key = value into a hash like so:

# config.txt name = foo name2 = foo2 ...

Here is my script:

# config.pl open(FILEHANDLE, "config.txt"); $values = {}; while ($line = <FILEHANDLE>) { $line =~ /^([^=]+)=(.*)/; $values{$1} = $2; }

but in the config file there might be whitespace before and after the '='. How would I get rid of it? I know it must be done with a regular expression. I got this reg exp. from a tutorial on perl.com and I don't completely understand how it works so if you could please explain your solution that would be great as I am really trying to learn.

Thanks

Edited 2001-05-01 by mirod: added <code> tags

Replies are listed 'Best First'.
Re: Read file and remove whitespace
by jeroenes (Priest) on May 01, 2001 at 09:56 UTC
    Next time, please embed your code in CODE tags, that will enlighten your post considerably ;-). Read the Site how to while you're at it.

    You already seem to have a firm grasp of regexs. You can read a bit more in perlre, Death to Dot Star! and 7 Stages of Regex Users. Look also at the links in regex tutorial, and of course at YAPE-Regex-Explain-1.01 released!. What you want, is simply an insertion of \s* around the '=' to allow any amount of whitespace to be read in.

    ... $line =~ /^([^=]+)\s*=\s*(.*)/;

    Furthermore, I would add a chomp $line; at the beginning of your while loop to remove newlines from your hash. Other issues: You don't check for the occurrence of a comment-line; If you only can have one '=', you'd better stick with split. That all results in:

    while( <> ){ next if /^#/; #check for comment next unless /=/; #check if = present chomp; #remove newline split /\s*=\s*/, $_, 2; #split line to @_ $values{ $_[0] } = $_[1]; #assign to hash }
    I used $_, it gets automagically assinged to by the while. Removes a bit of the code's complexity.

    Cheers,

    Jeroen
    "We are not alone"(FZ)

Answer: Read file and remove whitespace
by hdp (Beadle) on May 01, 2001 at 09:36 UTC
    while ($line = <>) { my ($k, $v) = split /\s*=\s*/, $line, 2; $values{$k} = $v; }
    Your code got a little mangled in the HTML (use <code> tags next time).

    I'm using split because what's before and after the = (and any surrounding whitespace) is irrelevant to the pattern -- what you really want to look for is that delimiter. split is natural for this job.

    hdp.

Re: Read file and remove whitespace
by grim (Initiate) on May 01, 2001 at 15:21 UTC
    Thanks that helps alot.
    I found out about the <code> after I posted and I could not figure out how to edit it.

    Thanks
Re: Read file and remove whitespace
by Sifmole (Chaplain) on May 01, 2001 at 17:19 UTC
    Hi,

    Since someone already explained about the regex, I just thought I would mention another possibility for you.

    I had an application which did something similar to what it looks like you are doing here. I found it simpler to turn the config.txt into a config.pm which could then be 'used' or 'required'. The list of "var=val" was turned into a hash, and that hash took the place of the %values hash that you are building by hand.

    Thus no need to write a something to parse it up, and it would allow any level of complexity that can be set up in a hash. This fact allowed the code to grow as new features were added to the system.

    Sincerely,
    Sifmole

      I am doing something similiar to this. I am reading the file from a module and turning it into a hash. However I want the ability to edit the config file via web form and I thought this would make it simple and easy. Thanks for the suggestion though

      Chris
Re: Read file and remove whitespace
by diarmuid (Beadle) on May 01, 2001 at 17:25 UTC
    Well this is what I would do
    while(<FILE>){ $values{$1}=$2 if(/^(\w+)\s*=\s*(\w+)$/); }
    So this loops through the file matching :
    1. Start of line
    2. One or more words Remember this
    3. Zero or more spaces
    4. Equals sign
    5. Zero or more spaces
    6. One or more words Remember this
    7. End of line
    And uses the two remembered words to create the hash

    Diarmuid