Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Regex to array

by kepler (Scribe)
on Jan 09, 2018 at 12:34 UTC ( #1206967=perlquestion: print w/replies, xml ) Need Help??
kepler has asked for the wisdom of the Perl Monks concerning the following question:


So I have a string (read from a file) that has sections; so 1 line says SECTION 1 and its values follows in the next lines, until SECTION 2, and so on...I splited the string like this:

my @groups = split /(SECTION \d+)/$string;

Is there a way of automatically assing to an hash array its respective values, that is, create an hash array where

$hasharray["SECTION 1"]
contains the respective values without a simple loop?

Kind regards


Replies are listed 'Best First'.
Re: Regex to array
by choroba (Bishop) on Jan 09, 2018 at 12:46 UTC
    The only problem is the empty field created by split at the start of the text, otherwise you'd have been able to assign the result directly to %sections. But you can create a false entry at the beginning and remove it later:
    #! /usr/bin/perl use warnings; use strict; my $text = << '__TEXT__'; SECTION 1 This is the first section. SECTION 2 And this is the second one. __TEXT__ my %section = ("", split /(SECTION \d+)/, $text); delete $section{""}; use Data::Dumper; print Dumper \%section;

    Update: Note that hashes use curly brackets, not the square ones (unlike in PHP).

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Or there's the option of using undef to ignore a value in a list. I don't remember where it's documented though: (undef, my %section) = split /(SECTION \d+)/, $text;

        ... where it's documented ...

        See List value constructors in perldata:

        ... you may assign to "undef" in a list. This is useful for throwing away some of the return values of a function ...
        Assignment to undef works for any list assignment, but if you're assigning from an array or list, it's usually more sane to use some kind of slice rather than fooling around with undef.

        Give a man a fish:  <%-{-{-{-<

Re: Regex to array
by Corion (Pope) on Jan 09, 2018 at 12:36 UTC

    If you trust that your data will be well-formed, you can simply match what you want to keep instead of splitting the string:

    my %values = ($string =~ /(SECTION \d+)\s+(.*?)/sg);

    That idea doesn't work :-/ :

    my $string = <<STR; SECTION 1 This is section 1 SECTION 2 This is section 2 STR use Data::Dumper; my %values = ($string =~ /(SECTION \d+)\s+(.*?)/sg); print Dumper \%values;

      It works if you add an end marker for the right part:

      use Data::Dump qw( pp ); my $str = <<_BLA_; SECTION 1 bla bla bla SECTION 2 blabla blabla SECTION 3 bla _BLA_ my %hash = $str =~ /(SECTION \d+)\s*(.*?)(?=SECTION|$)/sg; pp \%hash; __DATA__ { "SECTION 1" => "bla bla\nbla\n", "SECTION 2" => "blabla\nblabla\n", "SECTION 3" => "bla", }
      Edit: \s* rather than \s+ to allow empty section at EOF

        Greetings Eily

        Your solution was the only which made the job correctly done - thanks. Still, thanks to all too.

        Kind regards,


Re: Regex to array
by Laurent_R (Canon) on Jan 09, 2018 at 14:16 UTC
    Hi kepler,

    a slight variation on Corion's proposal, tested here at the command line:

    $ perl -e 'use strict; > use warnings; > use Data::Dumper; > > my $string = <<STR; STR> > SECTION 1 > > This is section 1 > > SECTION 2 > > This is section 2 > > STR > > > my %values = ($string =~ /(SECTION \d+)\s+([\w ]+)/mg); > print Dumper \%values; > ' $VAR1 = { 'SECTION 2' => 'This is section 2', 'SECTION 1' => 'This is section 1' };
    Edit: My computer froze when I was about to post this. I had to reboot. When I could start again to post, I did not notice that Eily had posted another solution fixing Corion's initial attempt.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1206967]
Front-paged by Arunbear
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (1)
As of 2018-08-18 14:09 GMT
Find Nodes?
    Voting Booth?
    Asked to put a square peg in a round hole, I would:

    Results (185 votes). Check out past polls.