Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

lowercasing during a match?

by mordibity (Acolyte)
on Aug 23, 2002 at 14:23 UTC ( [id://192333]=perlquestion: print w/replies, xml ) Need Help??

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

I have data like this:
my $raw = "foo=1 $baR= red BOO = 5.6 Baz =3";
I've found it very convenient to parse it like this:
my %params = $raw =~ /(\S+)\s*=\s*(\S+)/g;
Which gives me: (foo => 1, baR => "BOO", Baz => 3) However, ideally, I would like all the keys of my hash to be lowercase so I can than ignore case later when I do lookups. 'map { lc } ' won't work because I'm biting off tokens two at a time. Is there a Perlish way to do this all in one go? (ie, without capturing the matches in a separate step and lowercase the left-hand-side). Thanks!

Replies are listed 'Best First'.
Re: lowercasing during a match?
by jmcnamara (Monsignor) on Aug 23, 2002 at 14:58 UTC

    You could do $param{lc $key}; ;-)

    If it is okay to substitute the string you could do this:

    #!/usr/bin/perl -wl use strict; my $s = "FOO=1 BAR= RED BOO = 5.6 BAZ =3"; my %h; $h{lc $1} = $2 while $s =~ s/(\S+)\s*=\s*(\S+)//; print $_, "\t=> ", $h{$_} for keys %h; __END__ Prints: foo => 1 baz => 3 bar => RED boo => 5.6

    Or you could do something like this:

    #!/usr/bin/perl -wl use strict; my $s = "FOO=1 BAR= RED BOO = 5.6 BAZ =3"; my @a = split /[\s=]+/, $s; my %h = map {$_%2 ? $a[$_] : lc $a[$_]} 0..$#a; print $_, "\t=> ", $h{$_} for keys %h;

    --
    John.

Re: lowercasing during a match?
by fruiture (Curate) on Aug 23, 2002 at 14:38 UTC

    It is possible, but using a while loop is better:

    my $raw = "foo=1 baR= red BOO = 5.6 Baz =3"; my %params = (); use Benchmark qw/cmpthese/; my $test = { 'map' => sub { %params = map { (lc($_) => $raw =~ /$_\s*=\s*(\S+)/ ) } $raw =~ /(\S+)\s*=/g; %params = (); }, 'while' => sub { $params{lc($1)} = $2 while $raw =~ /(\S+)\s*=\s*(\S+)/g; %params = (); } }; #no regexp initialisation in benchmark $_->() for values %$test; cmpthese( -4 , $test );
    --
    http://fruiture.de
Re: lowercasing during a match?
by particle (Vicar) on Aug 23, 2002 at 15:46 UTC
    i can get you close... but you need a temp variable.

    my $count; my %params = map { ++$count % 2 ? lc : $_ } $raw =~ /(\S+)\s*=\s*(\S+) +/g;
    i guess you could take advantage of one of perl's predefined vars to save the my declaration, but you'll have to make sure it's okay to modify it in that scope...

    my %params = map { ++$. % 2 ? lc : $_ } $raw =~ /(\S+)\s*=\s*(\S+)/g;
    these are pretty obfuscated. why don't you do it in two clear steps instead?

    ~Particle *accelerates*

Re: lowercasing during a match?
by dws (Chancellor) on Aug 23, 2002 at 16:51 UTC
    Is there a Perlish way to do this all in one go?

    /e can be your friend. Try this:   $raw =~ s/(\S+?)\s*=\s*(\S+)/$params{lc($1)} = $2/ge; It's destructive on $raw, but that's easy enough to work around if you care.

Re: lowercasing during a match?
by BrowserUk (Patriarch) on Aug 23, 2002 at 14:46 UTC

    I'm not great with regexes but couldnt you do something like:

    my %params = $raw =~ s/(\s+)\s*=\s*(\S+)/lc($1)/e while ($raw =~ s/(\s ++)\s*=\s*(\S+)/);

    Updated to say it won't work - the loop will never terminate:( You'd need to use /c and or\G or something somewhere, but I said I ain't good with regexes!


    What's this about a "crooked mitre"? I'm good at woodwork!
Re: lowercasing during a match?
by fglock (Vicar) on Aug 23, 2002 at 14:36 UTC

    my %params = lc($raw) =~ ...

    It will lowercase everything, however :(

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-04-25 08:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found