Jax
Jax

Reputation: 7130

How can I split a string into chunks of two characters each in Perl?

How do I take a string in Perl and split it up into an array with entries two characters long each?

I attempted this:

@array = split(/../, $string);

but did not get the expected results.

Ultimately I want to turn something like this

F53CBBA476

in to an array containing

F5 3C BB A4 76

Upvotes: 37

Views: 56588

Answers (5)

Robbie Hatley
Robbie Hatley

Reputation: 129

I see a more-intuitive (if perhaps less-efficient) way to solve this issue: slice-off the required 2-character strings from the string with "substr" and push them onto the array with "push":

# Start with a string (a hex number in this case):
my $string = "526f62626965204861746c6579";

# Declare an array to hold the desired 2-char snippets:
my @array; 

# Snip snippets from string and put in array:
while ($string) {push @array, substr($string,0,2,"");}

# Say, those look like ASCII codes, don't they?
for (@array) {print chr(hex($_));}

Run that and see what it prints. :-)

Upvotes: 1

mat
mat

Reputation: 13353

If you really must use split, you can do a :

grep {length > 0} split(/(..)/, $string);

But I think the fastest way would be with unpack :

unpack("(A2)*", $string);

Both these methods have the "advantage" that if the string has an odd number of characters, it will output the last one on it's own.

Upvotes: 44

ikegami
ikegami

Reputation: 385764

The pattern passed to split identifies what separates that which you want. If you wanted to use split, you'd use something like

my @pairs = split /(?(?{ pos() % 2 })(?!))/, $string;

or

my @pairs = split /(?=(?:.{2})+\z)/s, $string;

Those are rather poor solutions. Better solutions include:

my @pairs = $string =~ /..?/sg;  # Accepts odd-length strings.

my @pairs = $string =~ /../sg;

my @pairs = unpack '(a2)*', $string;

Upvotes: 7

Bill Karwin
Bill Karwin

Reputation: 562310

@array = ( $string =~ m/../g );

The pattern-matching operator behaves in a special way in a list context in Perl. It processes the operation iteratively, matching the pattern against the remainder of the text after the previous match. Then the list is formed from all the text that matched during each application of the pattern-matching.

Upvotes: 61

ChrisD
ChrisD

Reputation: 71

Actually, to catch the odd character, you want to make the second character optional:

@array = ( $string =~ m/..?/g );

Upvotes: 7

Related Questions