Inline regex

Discussion in 'Perl Misc' started by steve, Oct 16, 2007.

  1. steve

    steve Guest

    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
     
    steve, Oct 16, 2007
    #1
    1. Advertising

  2. On Oct 16, 11:18 am, steve <> wrote:
    > 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;
     
    it_says_BALLS_on_your forehead, Oct 16, 2007
    #2
    1. Advertising

  3. steve

    Uri Guttman Guest

    >>>>> "isBoyf" == it says BALLS on your forehead <> writes:

    >> $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

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Oct 16, 2007
    #3
  4. steve

    steve Guest

    Christian Winter wrote:
    > steve wrote:
    >> 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
     
    steve, Oct 16, 2007
    #4
  5. steve

    J. Gleixner Guest

    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?
     
    J. Gleixner, Oct 16, 2007
    #5
  6. steve

    steve Guest

    Christian Winter wrote:
    > steve wrote:
    >> 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?
     
    steve, Oct 16, 2007
    #6
  7. steve

    steve Guest

    Christian Winter wrote:
    > steve wrote:
    >> 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?
     
    steve, Oct 16, 2007
    #7
  8. steve

    steve Guest

    steve wrote:
    > Christian Winter wrote:
    >> steve wrote:
    >>> 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...
     
    steve, Oct 16, 2007
    #8
  9. steve

    Paul Lalli Guest

    On Oct 16, 12:17 pm, steve <> wrote:
    > 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
     
    Paul Lalli, Oct 16, 2007
    #9
  10. On Oct 16, 11:30 am, Uri Guttman <> wrote:
    > >>>>> "isBoyf" == it says BALLS on your forehead <> writes:

    >
    > >> $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;
     
    it_says_BALLS_on_your forehead, Oct 16, 2007
    #10
  11. On Oct 16, 4:26 pm, Abigail <> wrote:

    > 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];
     
    Brian McCauley, Oct 16, 2007
    #11
  12. On Oct 16, 5:51 pm, it_says_BALLS_on_your forehead
    <> wrote:
    > On Oct 16, 11:30 am, Uri Guttman <> wrote:


    > 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;


    That still modifies @line.
     
    Brian McCauley, Oct 16, 2007
    #12
  13. On Oct 16, 1:14 pm, Brian McCauley <> wrote:
    > On Oct 16, 5:51 pm, it_says_BALLS_on_your forehead
    >
    > <> wrote:
    > > On Oct 16, 11:30 am, Uri Guttman <> wrote:
    > > 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;


    good grief! :)

    my @trimmed = map { my $val = $_; $val =~ s/\s+$//; $val } @line;
     
    it_says_BALLS_on_your forehead, Oct 16, 2007
    #13
  14. On Oct 16, 1:28 pm, it_says_BALLS_on_your forehead
    <> wrote:
    > On Oct 16, 1:14 pm, Brian McCauley <> wrote:
    >
    > > On Oct 16, 5:51 pm, it_says_BALLS_on_your forehead

    >
    > > <> wrote:
    > > > On Oct 16, 11:30 am, Uri Guttman <> wrote:
    > > > 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;

    >
    > 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?)
     
    it_says_BALLS_on_your forehead, Oct 16, 2007
    #14
  15. steve

    Mirco Wahab Guest

    Christian Winter wrote:
    > 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
     
    Mirco Wahab, Oct 16, 2007
    #15
  16. steve

    Uri Guttman Guest

    >>>>> "MW" == Mirco Wahab <-halle.de> writes:

    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

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Oct 16, 2007
    #16
  17. On Tue, 16 Oct 2007 15:22:48 -0000, it_says_BALLS_on_your forehead
    <> wrote:

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


    Nope!

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

    We don't have the subst() method yet.


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Oct 16, 2007
    #17
  18. On Tue, 16 Oct 2007 16:51:36 -0000, it_says_BALLS_on_your forehead
    <> wrote:

    >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
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Oct 16, 2007
    #18
  19. On Tue, 16 Oct 2007 17:32:21 -0000, it_says_BALLS_on_your forehead
    <> wrote:

    >> 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?)


    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
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Oct 16, 2007
    #19
  20. On Tue, 16 Oct 2007 16:17:50 GMT, steve <> wrote:

    >Wow, thanks for the quick response, that works nicely.
    >
    >Another quick question...


    Then you'd probably better start a new thread...


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Oct 16, 2007
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Abhi
    Replies:
    2
    Views:
    764
    E. Robert Tisdale
    Jul 3, 2003
  2. Alvin
    Replies:
    7
    Views:
    507
    E. Robert Tisdale
    May 6, 2005
  3. Replies:
    3
    Views:
    490
  4. Daniel Vallstrom
    Replies:
    2
    Views:
    2,040
    Kevin Bracey
    Nov 21, 2003
  5. Replies:
    3
    Views:
    822
    Reedick, Andrew
    Jul 1, 2008
Loading...

Share This Page