Question

I have a string str a\tb\tc\td\te

I want the 1st field value a to go in a variable, then 2nd field value b to go in other variable, then both c\td to go in 3rd variable and last field value e to go in one variable.

If I do

my ($a,$b,$c,$d) = split(/\t/,$_,4);

$c will acquire only c and $d will acquire d\te

I can do:

my ($a,$b,$c) = split(/\t/,$_,3);

Then c will get c\td\te and I can somehow (How?) get rid of last value and get it in $d

How to achieve this?

Was it helpful?

Solution

split is good when you're keeping the order. If you're breaking the ordering like this you have a bit of a problem. You have two choices:

  1. split according to \t and then join the ones you want.
  2. be explicit.

an example of the first choice is:

my ($a,$b,$c1, $c2, $d) = split /\t/, $_;
my $c = "$c1\t$c2";

an example of the second choice is:

my ($a, $b, $c, $d) = (/(.*?)\t(.*?)\t(.*?\t.*?)\t(.*?)/;

each set of parentheses captures what you want exactly. Using the non-greedy modifier (?) after the * ensures that the parentheses won't capture \t.


Edit: if the intent is to have an arbitrary number of variables, you're best off using an array:

my @x = split /\t/, $_;

my $a = $x[0];
my $b = $x[1];
my $c = join "\t", @x[2..($#x-1)];
my $d = $x[-1];

OTHER TIPS

You can use a regex with a negative look-ahead assertion, e.g.:

my @fields = split /\t(?!d)/, $string;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top