How to extract single characters or nested groupings from a string in Perl?

I would like to split the line: "Hello [You] All"

into the following array:

H, e, l, l, o, [You], A, l, l

I tried to do it with split:

my $str = "Hello[You]All";
my @list = split(/(\[.*?\]|.)/, $str);

foreach (@list) {
    print "->$_\n";
}

      

Since I tried something that split shouldn't do, it gave me the following array:

, H ,, e ,, l ,, l ,, o ,, [You] ,, A ,, l ,, l,

The next step I need to take is to remove the white spaces.

While not the best solution, it is the only one I found, without anything too messy. I am posting here to see if anyone knows a better way to solve this problem?

+2


source to share


3 answers


my $str = "Hello[You]All";
my @list = $str =~ /(\[.*?\]|.)/g;

foreach (@list) {
    print "->$_\n";
}

      



In other words: you don't need to split the template you are using (which causes these empty elements, because they are the actual text that was split using your template as the separator); you just need to extract all matches for your template. Which does global ( /g

) pattern matching in the context of an array.

+8


source


You can grep on nonblank items;

my @list = grep /./, split(/(\[.*?\]|.)/, $str);

      



As an alternative

my @list = $str =~ /\[.*?\]|./g;

      

+5


source


While I also think chaos's answer here is correct, for completeness, here's one way to achieve what you want to use split

and grep

:

#!/usr/bin/perl

use strict;
use warnings;

my $x = "Hello[You]All";
my @x = grep { defined } split qr{(\[.+\])|}, $x;

use Data::Dumper;
print Dumper \@x;

      

Using this pattern, it split

strips either into characters in parentheses (you didn't specify what "a[]b"

is valid input), or an empty string and filters grep

on defined

, not true.

+1


source







All Articles