split and join
| split | |
| The third argument | |
| split on whitespace | |
| join | |
| A round trip |
split
split cuts a string wherever the pattern matches and returns the pieces as a list. The pattern describes the separator, not the fields, which is the one thing to remember about it.
my $line = "ada:36:london";
my @fields = split /:/, $line;
print "@fields\n"; # ada 36 london
print scalar @fields, "\n"; # 3
perl demo.pl
ada 36 london
3
A plain string may be used instead of a pattern for a fixed separator, but the pattern form keeps the habit consistent and lets you add alternatives later, such as /[:,]/.
The third argument
By default split drops trailing empty fields, which is convenient for loose input and wrong for fixed columns. Give a limit as the third argument to keep them, or use a negative limit to keep every empty field.
my $csv = "a,b,,";
my @loose = split /,/, $csv; # a b
my @fixed = split /,/, $csv, -1; # a b and two empty fields
print scalar @fixed, "\n"; # 4
perl demo.pl
4
A positive limit caps the number of fields, and the remainder stays in the last one. That is how you split a line into key and value only once.
split on whitespace
The special pattern ' ', a single space in quotes, means split like awk: skip leading whitespace, split on runs of whitespace, and drop trailing whitespace. It is the right call for columns of text.
my $row = " alice 42 admin ";
my @cols = split ' ', $row;
print "@cols\n"; # alice 42 admin
perl demo.pl
alice 42 admin
Compare that with /\s+/, which leaves an empty first field when the line starts with a space. For command output, the quoted space is almost always the one you want.
join
join is the inverse: a separator and a list become one string. It is the safe way to build CSV-ish output, because you control the separator and the number of fields.
my @row = ("bob", 28, "dev");
my $line = join ",", @row;
print "$line\n"; # bob,28,dev
print join("\n", @row), "\n";
perl demo.pl
bob,28,dev
bob
28
dev
A round trip
split and join pair up in real scripts: read a line, change one field, write the line back. The example below also shows why a limit of 2 is useful.
my @cfg = split /\s*=\s*/, "timeout = 30", 2;
$cfg[1] = $cfg[1] * 2;
print join("=", @cfg), "\n"; # timeout=60
perl demo.pl
timeout=60
For real CSV with quoted commas, split is not enough. Lesson 41 shows Text::CSV, which handles the quoting rules for you.
Next: grep and map
Article author: Arthur Isaev