Map with Split & Trim in Perl

How to use a card with a split function to trim components: $ a, $ b, $ c and $ d; $ line?

my ($a, $b, $c, $d, $e) = split(/\t/, $line); # Perl trim function to remove whitespace from the start and end of the string sub trim($) { my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } 
+4
source share
6 answers

Do not use prototypes ($) for your function unless you need .

 my ( $a, $b, $c, $d, $e ) = map {s/^\s+|\s+$//g; $_} ## Notice the `, $_` this is common , split(/\t/, $line, 5) ; 

Do not forget that in the above s/// the replacement counter is returned - not $_ . So we do it explicitly.

or more simply:

 my @values = map {s/^\s+|\s+$//g; $_}, split(/\t/, $line, 5), $line 
+4
source

map accepts two inputs:

  • expression or block: it will be a trim expression (you do not need to write it yourself - it is on CPAN)
  • and list to work: this should be split output:
 use String::Util 'trim'; my @values = map { trim($_) } split /\t/, $line; 
+3
source

This should work:

 my ($a, $b, $c, $d, $e) = map {trim ($_)} (split(/\t/, $line)); 

By the way, this is a minor point, but you should not use $ a and $ b as variable names.

+2
source

You can also use "foreach" here.

 foreach my $i ($a, $b, $c, $d, $e) { $i=trim($i); } 
+1
source

Just for a change:

 my @trimmed = grep { s/^\s*|\s*$//g } split /\t/, $line; 

grep acts like a filter on lists. This is why \s+ needs to be changed to \s* inside the regular expression. Forced matches of 0 or more spaces prevent grep filtering out items in the list that do not have leading or trailing spaces.

0
source

When I crop a string, I don't often want to keep the original. It would be nice to have a sub abstraction, but also no need to fuss about temporary values.

Turns out we can do just that, as perlsub explains:

Any arguments passed are displayed in the @_ array. Therefore, if you call a function with two arguments, they will be stored in $_[0] and $_[1] . The @_ array is a local array, but its elements are aliases for real scalar parameters. In particular, if the element $_[0] updated, the corresponding argument is updated (or an error occurs if it is not updated).

In your case, trim becomes

 sub trim { for (@_) { s/^ \s+ //x; s/ \s+ $//x; } wantarray ? @_ : $_[0]; } 

Remember that map and for are cousins, so with a loop in trim you no longer need map . for instance

 my $line = "1\t 2\t3 \t 4 \t 5 \n"; my ($a, $b, $c, $d, $e) = split(/\t/, $line); print "BEFORE: [", join("] [" => $a, $b, $c, $d), "]\n"; trim $a, $b, $c, $d; print "AFTER: [", join("] [" => $a, $b, $c, $d), "]\n"; 

Conclusion:

  BEFORE: [1] [2] [3] [4]
 AFTER: [1] [2] [3] [4] 
0
source

Source: https://habr.com/ru/post/1314506/


All Articles