Wow....Thank you thank you very much, Chas. Owens, that's great...appreciate that :-)
William ----- Original Message ---- > From: Chas. Owens <chas.ow...@gmail.com> > To: William <esia...@yahoo.com> > Cc: beginner perl mailling list <beginners@perl.org> > Sent: Friday, June 5, 2009 22:01:41 > Subject: Re: parsing data structure > > On Fri, Jun 5, 2009 at 09:19, William wrote: > > > > I have been trying for hours, to make this data structure into hash, I need > help. Thanks. > > > > $str = > > " > > (dr1 > > foo > > <1>(dr2 bar) > > <2>a > > ) > > "; > > > > $hash = { > > "dr1" => { > > "<1>" => {"dr2" => {"predicate"=> "bar"}}, > > "<2>" => "a" > > } > > }; > snip > > What could be the regular expression and algorithm to make the resulting > > hash > ? > snip > > This isn't really a job for a regex. Note that you have a recursive > structure (parentheses can contain parentheses). When you have a > recursive structure you are moving out of the realm of regexes and > into the realm of parsers. A good general purpose parser is > Parse::RecDescent[1], and you should learn to use it, but your example > is simple enough that we don't need it. We can tokenize the stream > fairly easily by splitting on '(', ')', '<', '>', and whitespace, then > throwing out the whitespace characters[2]. Once we have the tokens we > deal with each () group recursively: > > #!/usr/bin/perl > > use strict; > use warnings; > > my $s = " > (dr1 > foo > <1>(dr2 bar) > <2>a > ) > "; > > my @tokens = grep { /\S/ } split /([()<>\s])/, $s; > > my $hash = recurse(\...@tokens); > > use Data::Dumper; > print Dumper $hash; > > sub recurse { > my $tokens = shift; > my $paren = shift @$tokens; > my $key = shift @$tokens; > die "invalid structure" unless $paren eq '('; > > my %hash; > while (@$tokens) { > my $start = shift @$tokens; > my $subkey = shift @$tokens; > my $end = shift @$tokens; > die "invalid structure" unless $start eq '<' and $end eq '>'; > > if ($tokens->[0] eq '(') { > $hash{$key}{$subkey} = recurse($tokens); > } else { > $hash{$key}{$subkey} = shift @$tokens; > } > > if ($tokens->[0] eq ')') { > shift @$tokens; > return \%hash; > } > } > > die "invalid structure"; > } > > 1. http://search.cpan.org/dist/Parse-RecDescent/lib/Parse/RecDescent.pm > 2. if whitespace is allowed between '<' and '>', this will need to > change slightly > > -- > Chas. Owens > wonkden.net > The most important skill a programmer can have is the ability to read. > > -- > To unsubscribe, e-mail: beginners-unsubscr...@perl.org > For additional commands, e-mail: beginners-h...@perl.org > http://learn.perl.org/ New Email names for you! Get the Email name you've always wanted on the new @ymail and @rocketmail. Hurry before someone else does! http://mail.promotions.yahoo.com/newdomains/aa/ -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/