Inline regex

S

steve

Hi all,

I am currently working on a small script that parses text files and
outputs them in a different format, to be used by another program. I am
constantly removing trailing whitespace like so:

$desc = $line[7]; # @line is an array derived from a line in a CSV file
$desc =~ s/\s+$//g; # Trim trailing whitespace

But this is in two lines. How can I copy the variable and remove
whitespace in one line of code?

I know I don't need to, but I tried and failed and now am curious.

Thanks
steve
 
I

it_says_BALLS_on_your forehead

Hi all,

I am currently working on a small script that parses text files and
outputs them in a different format, to be used by another program. I am
constantly removing trailing whitespace like so:

$desc = $line[7]; # @line is an array derived from a line in a CSV file
$desc =~ s/\s+$//g; # Trim trailing whitespace

But this is in two lines. How can I copy the variable and remove
whitespace in one line of code?

if you're concerned with brevity of code, you could always use a map.

e.g.

my @trimmed = map { s/\s+$// } @line;
 
U

Uri Guttman

isBoyf" == it says BALLS on your forehead said:
$desc = $line[7]; # @line is an array derived from a line in a CSV file
$desc =~ s/\s+$//g; # Trim trailing whitespace

But this is in two lines. How can I copy the variable and remove
whitespace in one line of code?

isBoyf> if you're concerned with brevity of code, you could always use a map.

isBoyf> my @trimmed = map { s/\s+$// } @line;

hmm, have you tested that? i don't think you will like the results.

uri
 
S

steve

Christian said:
steve said:
I am currently working on a small script that parses text files and
outputs them in a different format, to be used by another program. I
am constantly removing trailing whitespace like so:

$desc = $line[7]; # @line is an array derived from a line in a CSV
file
$desc =~ s/\s+$//g; # Trim trailing whitespace

But this is in two lines. How can I copy the variable and remove
whitespace in one line of code?

I know I don't need to, but I tried and failed and now am curious.

If you want to do the assignment and replacement in one line, you'll
just have to consider operator precedence as diplayed in "perldoc
perlop". The regex comparison operator "=~" binds tighter than
the simple assignment "=", therefore a simple

my $desc = $line[7] =~ s/\s+$//;

won't do that and rather assign the result of the regex replacement
to $desc (btw., no need for the /g modifier there, you already take
care of multiple spaces with the greedy + multiplier). However, simple
brackets suffice to tell perl the order of processing you want:

(my $desc = $line[7]) =~ s/\s+$//;

That's about as short as one can make it.

-Chris

Wow, thanks for the quick response!

Would the code you suggested remove the whitespace from $line[7] as well?

steve
 
J

J. Gleixner

steve wrote:
[...]
Wow, thanks for the quick response!

Would the code you suggested remove the whitespace from $line[7] as well?

ahhhh. Why not try it and see for yourself?
 
S

steve

Christian said:
steve said:
I am currently working on a small script that parses text files and
outputs them in a different format, to be used by another program. I
am constantly removing trailing whitespace like so:

$desc = $line[7]; # @line is an array derived from a line in a CSV
file
$desc =~ s/\s+$//g; # Trim trailing whitespace

But this is in two lines. How can I copy the variable and remove
whitespace in one line of code?

I know I don't need to, but I tried and failed and now am curious.

If you want to do the assignment and replacement in one line, you'll
just have to consider operator precedence as diplayed in "perldoc
perlop". The regex comparison operator "=~" binds tighter than
the simple assignment "=", therefore a simple

my $desc = $line[7] =~ s/\s+$//;

won't do that and rather assign the result of the regex replacement
to $desc (btw., no need for the /g modifier there, you already take
care of multiple spaces with the greedy + multiplier). However, simple
brackets suffice to tell perl the order of processing you want:

(my $desc = $line[7]) =~ s/\s+$//;

That's about as short as one can make it.

-Chris

Wow, thanks for the quick response, that works nicely.

Another quick question...
I have a variable that is padded with leading zeros (e.g. "0001.125"). I
want to be able to remove all leading zeros if the value >= 1 ("1.125"),
but leave one leading zero if the value < 1 (e.g. "0000.125" should
become "0.125" not ".125"). Can I do this with one regex?
 
S

steve

Christian said:
steve said:
I am currently working on a small script that parses text files and
outputs them in a different format, to be used by another program. I
am constantly removing trailing whitespace like so:

$desc = $line[7]; # @line is an array derived from a line in a CSV
file
$desc =~ s/\s+$//g; # Trim trailing whitespace

But this is in two lines. How can I copy the variable and remove
whitespace in one line of code?

I know I don't need to, but I tried and failed and now am curious.

If you want to do the assignment and replacement in one line, you'll
just have to consider operator precedence as diplayed in "perldoc
perlop". The regex comparison operator "=~" binds tighter than
the simple assignment "=", therefore a simple

my $desc = $line[7] =~ s/\s+$//;

won't do that and rather assign the result of the regex replacement
to $desc (btw., no need for the /g modifier there, you already take
care of multiple spaces with the greedy + multiplier). However, simple
brackets suffice to tell perl the order of processing you want:

(my $desc = $line[7]) =~ s/\s+$//;

That's about as short as one can make it.

-Chris

Wow, thanks for the quick response, that works nicely.

Another quick question...
I have a variable that is padded with leading zeros (e.g. "0001.125"). I
want to be able to remove all leading zeros if the value >= 1 ("1.125"),
but leave one leading zero if the value < 1 (e.g. "0000.125" should
become "0.125" not ".125"). Can I do this with one regex?
 
S

steve

steve said:
Christian said:
steve said:
I am currently working on a small script that parses text files and
outputs them in a different format, to be used by another program. I
am constantly removing trailing whitespace like so:

$desc = $line[7]; # @line is an array derived from a line in a CSV
file
$desc =~ s/\s+$//g; # Trim trailing whitespace

But this is in two lines. How can I copy the variable and remove
whitespace in one line of code?

I know I don't need to, but I tried and failed and now am curious.

If you want to do the assignment and replacement in one line, you'll
just have to consider operator precedence as diplayed in "perldoc
perlop". The regex comparison operator "=~" binds tighter than
the simple assignment "=", therefore a simple

my $desc = $line[7] =~ s/\s+$//;

won't do that and rather assign the result of the regex replacement
to $desc (btw., no need for the /g modifier there, you already take
care of multiple spaces with the greedy + multiplier). However, simple
brackets suffice to tell perl the order of processing you want:

(my $desc = $line[7]) =~ s/\s+$//;

That's about as short as one can make it.

-Chris

Wow, thanks for the quick response, that works nicely.

Another quick question...
I have a variable that is padded with leading zeros (e.g. "0001.125"). I
want to be able to remove all leading zeros if the value >= 1 ("1.125"),
but leave one leading zero if the value < 1 (e.g. "0000.125" should
become "0.125" not ".125"). Can I do this with one regex?

Apologies for the duplicate posts, thunderbird is being a benny...
 
P

Paul Lalli

I have a variable that is padded with leading zeros
(e.g. "0001.125"). I want to be able to remove all leading zeros
if the value >= 1 ("1.125"), but leave one leading zero if the
value < 1 (e.g. "0000.125" should become "0.125" not ".125"). Can
I do this with one regex?

You can, with look-aheads:
$x =~ s/^0+(?!\.)//;

But depending on your data, sprintf() might be simpler.

$x = sprintf('%.3f', $x);

Or, just tell Perl that it really is a number, which might be simpler
still:

$x += 0;

Paul Lalli
 
I

it_says_BALLS_on_your forehead

$desc = $line[7]; # @line is an array derived from a line in a CSV file
$desc =~ s/\s+$//g; # Trim trailing whitespace

But this is in two lines. How can I copy the variable and remove
whitespace in one line of code?

isBoyf> if you're concerned with brevity of code, you could always use a map.

isBoyf> my @trimmed = map { s/\s+$// } @line;

hmm, have you tested that? i don't think you will like the results.

stupid mistake :-(.

my @trimmed = map { s/\s+$//; $_ } @line;
 
B

Brian McCauley

Or, if I have to write it in one line, my first preference would be:

$desc = $line [7]; $desc =~ s/\s+$//; # No need for /g.

Second choice:

($desc = $line [7]) =~ s/\s+$//; # No need for /g.

If you really don't like the above format I have some syntactic sugar
for you.

use List::MoreUtils qw ( apply );
my $desc = apply { s/\s+$// } $line[7];
 
I

it_says_BALLS_on_your forehead

good grief! :)

my @trimmed = map { my $val = $_; $val =~ s/\s+$//; $val } @line;
 
I

it_says_BALLS_on_your forehead

good grief! :)

my @trimmed = map { my $val = $_; $val =~ s/\s+$//; $val } @line;

OR, if you WANT to change the original @line:

map { s/\s+$// } @line;

(not sure, but i believe that map in void context is fine in >= 5.8.7,
correct?)
 
M

Mirco Wahab

Christian said:
I tend to shun a map without use of its return values like
the devil the holy water, as the same can be accomplished
with a for loop, and the intention is clearer to whoever
gets to maintain my code.

s/\s+$// for @line;

Where the 'map' would (imho) make sense:

...
my @trimmed = map /\s+$/ ? substr($_,0,$-[0]) : $_, @line;
...



(anybody interested in banchmarking the
non-modifying varieties ;-)



Regards

Mirco
 
U

Uri Guttman

MW> Where the 'map' would (imho) make sense:

MW> ...
MW> my @trimmed = map /\s+$/ ? substr($_,0,$-[0]) : $_, @line;
MW> ...

why the extra code? just grab the text before the trailing spaces (untested):

my @trimmed = map /^(.*?)\s*$/, @line;

note the use of * in both parts as either can be empty. dunno if this
will run fast or slow due to the double use of *. but as i said in
another thread, trimming white space is so trivial in perl so why waste
effort on doing it in different ways.

uri
 
M

Michele Dondi

stupid mistake :-(.

my @trimmed = map { s/\s+$//; $_ } @line;

Stupid Mistake II the Revenge: you will modify @line too, which may be
what you want or not, but generally isn't. In that case you would just

s/\s+$// for @line;


Michele
 
M

Michele Dondi

OR, if you WANT to change the original @line:

map { s/\s+$// } @line;

(not sure, but i believe that map in void context is fine in >= 5.8.7,
correct?)

It is fine but considered bad, for good reasons. You would use C<for>
in that case, since that's exactly what it's... for!


Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top