Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Convert string to data structure

by Dirk80 (Pilgrim)
on Sep 21, 2012 at 15:25 UTC ( [id://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

Replies are listed 'Best First'.
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 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 (Archbishop) 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 (Sage) 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 johngg (Canon) 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 (Patriarch) 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 (Paladin) 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
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (8)
As of 2024-04-25 11:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found