Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Convert string to data structure

by Dirk80 (Monk)
on Sep 21, 2012 at 15:25 UTC ( #994923=perlquestion: print w/ replies, xml ) Need Help??
Dirk80 has asked for the wisdom of the Perl Monks concerning the following question:

Hello

possibly this is an easy thing. But I don't get it. So I'm interested in your answers.

Here my string:

my $str = "1. ...... AB_CD 1.1 ...... EF_GH 1.2 .... IJ_KL_MN 2. ............ OPQR";

And here what I would like to have:

my $VAR1 = [{'chapter' => 1, 'name' => 'AB_CD'},{'chapter' => 1.1,'nam +e' => 'EF_GH'},{'chapter' => 1.2,'name' => 'IJ_KL_MN'},{'chapter' => +2,'name' => 'OPQR'}];

I tried a lot of things with split. And I often came near to the desired result. But as said before. I didn't get it completely correctly.

Example I tried: split(/\s\.+\s/, $str);

Thanks alot for your help.

Greetings, Dirk

Comment on Convert string to data structure
Select or Download Code
Re: Convert string to data structure
by Limbic~Region (Chancellor) on Sep 21, 2012 at 15:40 UTC
    Dirk80,
    Something like this untested code might work:
    my @token = split ' ', $str; for my $idx (reverse 0 .. $#token) { my $item = $token[$idx]; $item =~ s/\.+$//; splice(@token, $idx, 1) if ! length($item); } my @structure; for my $idx (grep {$_ % 2} 1 .. $#token) { push @structure, { chapter => $token{$idx - 1}, name => $toekn{$idx} }; }

    Cheers - L~R

Re: Convert string to data structure
by Athanasius (Monsignor) on Sep 21, 2012 at 15:52 UTC

    Another variation on the theme:

    #! perl use strict; use warnings; use Data::Dumper; my $str = "1. ...... AB_CD 1.1 ...... EF_GH 1.2 .... IJ_KL_MN 2. ..... +....... OPQR"; $str =~ s/ \.{2,} //gx; $str =~ s/ \.\s //gx; my %terms = split(/\s+/, $str); my @array; push @array, { 'chapter' => $_, 'name' => $terms{$_} } for sort keys % +terms; print Dumper(\@array);

    Output:

    $VAR1 = [ { 'name' => 'AB_CD', 'chapter' => '1' }, { 'name' => 'EF_GH', 'chapter' => '1.1' }, { 'name' => 'IJ_KL_MN', 'chapter' => '1.2' }, { 'name' => 'OPQR', 'chapter' => '2' } ];

    Hope that helps,

    Athanasius <°(((><contra mundum

Re: Convert string to data structure (split)
by tye (Cardinal) on Sep 21, 2012 at 15:56 UTC
    my $str = "1. ...... AB_CD 1.1 ...... EF_GH 1.2 .... IJ_KL_MN 2. ..... +....... OPQR"; my( undef, %chap ) = split /\s*(\d+\.\d*)\s*\.+\s*/, $str;

    Works.

    - tye        

      tye, I think you need to change:

      split/\s+(\d+ ... # ^

      to

      split/\s*(\d+ ... # ^

      otherwise it fails to capture '1.' => 'AB_CD'.

      Athanasius <°(((><contra mundum

        I did. Three times. Not sure how it still ended up not submitted that way. Thanks for pointing it out. :)

        - tye        

Re: Convert string to data structure
by Kenosis (Priest) on Sep 21, 2012 at 16:02 UTC

    Here's another option:

    use Modern::Perl; use Data::Dumper; my @array; my $str = "1. ...... AB_CD 1.1 ...... EF_GH 1.2 .... IJ_KL_MN 2. ............ +OPQR"; while ( $str =~ /(\d+\.\d*)\s+\.+\s+(\S+)\s*/g ) { push @array, { chapter => $1, name => $2 }; } say Dumper \@array;

    Output:

    $VAR1 = [ { 'name' => 'AB_CD', 'chapter' => '1.' }, { 'name' => 'EF_GH', 'chapter' => '1.1' }, { 'name' => 'IJ_KL_MN', 'chapter' => '1.2' }, { 'name' => 'OPQR', 'chapter' => '2.' } ];

    The regex:

    /(\d+\.\d*)\s+\.+\s+(\S+)\s*/g ^ ^ ^ ^ ^ ^ ^ ^ ^ | | | | | | | | | | | | | | | | | + - Globally | | | | | | | + - 0+ spaces | | | | | | + - Capture non-whitespace characters | | | | | + - 1+ spaces | | | | + - Multiple periods | | | + - 1+ spaces | | + - Capture zero or more digits | + - Capture a period + - Capture one or more digits

    Hope this helps!

      Thank you very much. All your answers are so great. And it was interesting to try all. A lot of great techniques. I could learn a lot of new skills and got ideas how to solve such a problem.

      Especially this solution "matching operator in global mode" I like because it is very easy to understand.

Re: Convert string to data structure
by johngg (Abbot) on Sep 21, 2012 at 16:52 UTC

    A variation using splits and maps.

    $ perl -MData::Dumper -Mstrict -Mwarnings -E ' > my $str = > q{1. ...... AB_CD 1.1 ...... EF_GH 1.2 .... IJ_KL_MN 2. ......... +... OPQR}; > my $raChapters = [ > map { { chapter => $_->[ 0 ], name => $_->[ 1 ] } } > map { [ split m{[. ]{2,}} ] } > split m{ (?=\d)}, $str > ]; > print Data::Dumper->Dumpxs( [ $raChapters ], [ qw{ raChapters } ] ); +' $raChapters = [ { 'name' => 'AB_CD', 'chapter' => '1' }, { 'name' => 'EF_GH', 'chapter' => '1.1' }, { 'name' => 'IJ_KL_MN', 'chapter' => '1.2' }, { 'name' => 'OPQR', 'chapter' => '2' } ]; $

    Cheers,

    JohnGG

Re: Convert string to data structure
by BrowserUk (Pope) on Sep 21, 2012 at 18:28 UTC

    $s = "1. ...... AB_CD 1.1 ...... EF_GH 1.2 .... IJ_KL_MN 2. .......... +.. OPQR";; @a = map{ /(\S+)\s+\.+\s+(\S+)/; { chapter => $1, name => $2 } } split '(?<=[^.])\s(?=[^.])', $s;; pp \@a;; [ { chapter => "1.", name => "AB_CD" }, { chapter => "1.1", name => "EF_GH" }, { chapter => "1.2", name => "IJ_KL_MN" }, { chapter => "2.", name => "OPQR" }, ]

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    RIP Neil Armstrong

Re: Convert string to data structure
by jdporter (Canon) on Sep 21, 2012 at 18:44 UTC
    my @a = map { my %h; @h{qw( chapter name )} = split / \.+ /; \%h } split / (?=\d)/, $str;

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2014-09-22 00:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (176 votes), past polls