Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserving White Space in qw

Tags:

perl

Is there any way to preserve some white space in qw? For example:

my @a=qw(1234 John Smith 123 Main St.);

will produce an array containing 6 elements. Is there any way to, oh I don't know... escape the white space to keep some of it? Something like:

my @a=qw(1234 John\ Smith 123\ Main\ St.);

to return 3 elements: '1234', 'John Smith', '123 Main St.'?

(FYI, I've tried the above, also with varying combinations of quotes, all to no avail)

like image 618
mswanberg Avatar asked Dec 31 '13 14:12

mswanberg


4 Answers

To just separate by newlines:

my @a = split /\n/, <<'END';
1234
John Smith
123 Main St.
END
like image 146
ysth Avatar answered Nov 17 '22 21:11

ysth


No, you cannot preserve whitespace with qw. As mpapec mentions in the comments, qw is for quoting words. Here are a few alternatives:

Simple array

my @a = ('1234', 'John Smith', '123 Main St.');

Heredoc + split

my $string = <<'END';
1234
John Smith
123 Main St.
END

my @a = split /\n/, $string;

__DATA__

my @a = <DATA>;
chomp @a;

__DATA__
1234
John Smith
123 Main St.

Multiple __DATA__ areas with Inline::Files

Credit goes to dga from this PerlMonks thread on the same topic.

Disclaimer: This module is experimental. Take note of the following warning from the documentation:

It is possible that this module may overwrite the source code in files that use it. To protect yourself against this possibility, you are strongly advised to use the -backup option described in "Safety first".

Be careful if you go this route.

use Inline::Files;

my @a = <FOO>;
chomp @a;

my @b = <BAR>;
chomp @b;

__FOO__
1234
John Smith
123 Main St.

__BAR__
5678
Jane Doe
456 Anonymous Ln.

External flat data files

It's often a bad idea to hard-code data into your scripts, so in general this is the route I would go.

data.txt

1234
John Smith
123 Main St.

myscript

open my $fh, "<", "data.txt" or die $!;

my @a = <$fh>;
chomp @a;

close $fh;

External CSV

data.csv

1234,"John Smith","123 Main St."
5678,"Jane Doe","456 Anonymous Ln."

myscript

use Text::CSV;

my $csv = Text::CSV->new() or die Text::CSV->error_diag();

open my $fh, "<", "data.csv" or die $!;

while (my $row = $csv->getline($fh)) { 
    # $row is an arrayref
}
$csv->eof or $csv->error_diag();

close $fh;

Relational Database???

Now I'm just being facetious. My point is, there's more than one way to skin this cat.

like image 45
ThisSuitIsBlackNot Avatar answered Nov 17 '22 21:11

ThisSuitIsBlackNot


If you have lots of such records, read them in from a text file and use split() to get the individual elements of the records. If your input text file doesn't have proper column separators then you might be better off fixing the input file somehow (e.g. by modifying the program that produced it in the first place). If you use __DATA__ you will still need to get the column separators right. I suggest you use tabs as column separators but any character which you are sure does not exist in your data will do.

like image 1
chandra Avatar answered Nov 17 '22 21:11

chandra


There multiple way to do it. My favorite is to choose a specific escape sequence to replace spaces. For example _:

my @a = qw(A_B C);
y/_/ / for @a;

or a more elaborate sequence like _SPACE_:

my @a = qw(A_SPACE_B C);
s/_SPACE_/ /g for @a;
like image 1
Jérôme Pouiller Avatar answered Nov 17 '22 21:11

Jérôme Pouiller