For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > June 2007 > Conditional in regex









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Conditional in regex
Jeff

2007-06-23, 10:02 pm


Hi all. I'm new to perl, a new programmer, and I badly need guidance. I'm
trying to parse a config file with key/value pairs seperated by white space
and surrounded by curly brackets. It has multiple fields that look like
this:

{
Key value
Key value
}

My solution has been to parse it with something simple --

while ($file_contents =~ /(\w+)\s*\{([^}]*)\}/gs) {
push @new, $2;
}

foreach (@new){
$_ =~ /\b(\w+)\s+(.*)\s+
\b(\w+)\s+(.*)/xgs;

My @next_tmp_variable = ($1, $2, etc);
}

-- but the config definitions contained in those curly brackets are
different lengths. Some only have a four left hand values, while others have
six or more. My solution isn't giving me what I really need.

So I have two questions. First, I don't understand how to test this so that
I parse all the values between the curly braces, regardless of how many
items are there. Second, and equally important, what kind of data structure
should I put the results in? I think I need a hash of hashes. What I'd like
to do is assign each left hand value as the key in a hash. Then, in each set
there's a left 'command' where the right hand value will always be unique,
which would be perfect for use as the name of an alias for the hash or as
the key to a reference to a hash of that definition. Is there a better way?
What's the best method for assigning all that stuff?

Thanks!


Tom Phoenix

2007-06-23, 10:02 pm

On 6/23/07, Jeff <pl@loserville.org> wrote:

> trying to parse a config file with key/value pairs seperated by white space
> and surrounded by curly brackets. It has multiple fields that look like
> this:
>
> {
> Key value
> Key value
> }


I'll bet it would be easy to parse with Parse::RecDescent.

http://search.cpan.org/~dconway/Par.../RecDescent.pod

Hope this helps!

--Tom Phoenix
Stonehenge Perl Training
Nobull67@Gmail.Com

2007-06-24, 6:59 pm

On Jun 24, 3:31 am, p...@loserville.org (Jeff) wrote:
> Hi all. I'm new to perl, a new programmer, and I badly need guidance. I'm
> trying to parse a config file with key/value pairs seperated by white space
> and surrounded by curly brackets. It has multiple fields that look like
> this:
>
> {
> Key value
> Key value
>
> }
>
> My solution has been to parse it with something simple --
>
> while ($file_contents =~ /(\w+)\s*\{([^}]*)\}/gs) {
> push @new, $2;
>
> }
>
> foreach (@new){
> $_ =~ /\b(\w+)\s+(.*)\s+
> \b(\w+)\s+(.*)/xgs;
>
> My @next_tmp_variable = ($1, $2, etc);
>
> }
>
> -- but the config definitions contained in those curly brackets are
> different lengths. Some only have a four left hand values, while others have
> six or more. My solution isn't giving me what I really need.


It's actually very close.

The =~ is redundant since $_ is the default.

There's no need for the intermediate variables.

Are newlines significant? Or can just treat it as a list of
alternating keys and values delimited by whitespace?

> So I have two questions. First, I don't understand how to test this so that
> I parse all the values between the curly braces, regardless of how many
> items are there.


You don't need to repeat the pattern by hand - the /g will do that for
you.

> Second, and equally important, what kind of data structure
> should I put the results in? I think I need a hash of hashes


Probably a list of hashes would be the most natural.

my @LoH = map { { split } } $file_contents =~ /\{(.*?)\}/gs;

>. What I'd like
> to do is assign each left hand value as the key in a hash. Then, in each set
> there's a left 'command' where the right hand value will always be unique,
> which would be perfect for use as the name of an alias for the hash or as
> the key to a reference to a hash of that definition.


my %HoH;
while ( $file_contents =~ /\{(.*?)\}/gs ) {
my %entry = split;
$HoH{delete $entry{command}} = \%entry;
}


John W. Krahn

2007-06-24, 6:59 pm

nobull67@gmail.com wrote:
> On Jun 24, 3:31 am, p...@loserville.org (Jeff) wrote:
>
> Probably a list of hashes would be the most natural.
>
> my @LoH = map { { split } } $file_contents =~ /\{(.*?)\}/gs;
>
>
> my %HoH;
> while ( $file_contents =~ /\{(.*?)\}/gs ) {
> my %entry = split;
> $HoH{delete $entry{command}} = \%entry;
> }


Shouldn't that be:

while ( $file_contents =~ /\{(.*?)\}/gs ) {
my %entry = split ' ', $1;
$HoH{delete $entry{command}} = \%entry;
}



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
Jeff

2007-06-24, 9:59 pm




On 6/24/07 10:42 AM, "nobull67@gmail.com" <nobull67@gmail.com> wrote:


> You don't need to repeat the pattern by hand - the /g will do that for
> you.
>

Thanks to everyone for the replies.

I expected what you pointed out above, that /\b(w+)\s+(\w+)\s+/gs would
match every instance of the pattern. Instead I got wildly results, with
random letters in some variables and the values I wanted in a different
offset every time. I cannot explain that, but the pattern works with the
left hand values written as literals (/\b(word)\s+(.*)\s+/)

> Are newlines significant? Or can just treat it as a list of
> alternating keys and values delimited by whitespace?
>

This can be treated as key/values delimited by whitespace.

I wonder if the unexpected results could be related to tabs or something
else besides \n? How do I see what's used for white space? Shouldn't \s
match any whitespace character?


> Probably a list of hashes would be the most natural.
>
> my @LoH = map { { split } } $file_contents =~ /\{(.*?)\}/gs;


Thanks. That's . Since this is the beginner's list, I'll just dive in
and ask a(nother) dumb question. I'm not sure I understand the double curly
braces around split. Would you mind showing me that in a less terse form?





John W. Krahn

2007-06-25, 7:59 am

Jeff wrote:
>
> On 6/24/07 10:42 AM, "nobull67@gmail.com" <nobull67@gmail.com> wrote:
>
> Thanks. That's . Since this is the beginner's list, I'll just dive in
> and ask a(nother) dumb question. I'm not sure I understand the double curly
> braces around split. Would you mind showing me that in a less terse form?


The outer curly braces are map's code block and the inner curly braces are an
anonymous hash.


John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
Krackavskoon

2007-06-25, 2:33 pm

http://www.eyrenet.com/Player.wmv?watch=1673286
Nobull67@Gmail.Com

2007-06-25, 9:59 pm

On Jun 24, 9:05 pm, kra...@telus.net (John W. Krahn) wrote:
> nobul...@gmail.com wrote:
>
>
>
>
>
>
> Shouldn't that be:
>
> while ( $file_contents =~ /\{(.*?)\}/gs ) {
> my %entry = split ' ', $1;
> $HoH{delete $entry{command}} = \%entry;
>
> }


Well actually I'd meant foreach() rather than while(). But using
while() and $1 is arguably better.

Pemetapmendes47

2007-06-25, 10:55 pm

Direct access to a famous adult site's member zone
http://online-sex-video.com/memberz...eo.php?file=301
http://online-sex-video.com/memberz...eo.php?file=302
http://online-sex-video.com/memberz...eo.php?file=303
http://online-sex-video.com/memberz...eo.php?file=304
change the number in the link to get other videos! There are hundreds!

username: 218571
password: peters
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com