简体   繁体   中英

How do I extract single characters or enclosed groupings from a string in Perl?

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

to 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 is not supposed to do, it gave me the following array:

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

Next step I need to take is to remove the empty spaces.

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

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

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

Which is to say: you don't need to split on the pattern you're using (which causes those empty elements, because they're the actual text that's been split out using your pattern as a divider); you just need to extract all matches for your pattern. Which doing a global ( /g ) pattern match in array context does.

You could grep the results for non-empty elements;

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

Alternatively,

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

While I also think chaos' answer is the right one here, for completeness, here is one way of achieving what you want using 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, split splits either on characters within brackets (you did not mention if "a[]b" is a valid input) or the empty string and the grep filters on defined ness rather than truth value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM