How can I remove trailing commas?

J

Jame Pearl

How can I remove any trailing commas from the end of $var?

I tried using

$var =~ s/,+$//

but it didn't work.
 
P

Paul Lalli

Jame said:
How can I remove any trailing commas from the end of $var?

I tried using

$var =~ s/,+$//

but it didn't work.

"Didn't work" is the worst of all possible error descriptions. *How*
did it not work? Did it not remove anything? Did it remove too much?
Did you get a syntax error (and if so, what was it?) Did your program
crash? Enter an infinite loop? *What happened*?

Please read the Posting Guidelines for this group. Then post a
short-but-complete example that we can run by copy and pasting, which
demonstrates your supposed error.

There is nothing wrong with that statement you have typed above.
Therefore, you have misdiagnosed your problem or mis-retyped your
actual code. This is why you are encouraged to create a
short-but-complete program in preparation for posting here - doing so
very often helps you find your *real* problem.

Now, all that being said, I have to ask how this need arose in the
first place? I've seen lots of bad code where people attempt to create
a string composed of the elements of an array separated by a comma, and
do so by concatenating each element of the array with a comma, and then
remove the final comma, like so:

my $string;
foreach my $elem (@array) {
$string .= "$elem,";
}
$string =~ s/,$//;
print "Values: $string\n";

If you are doing that, please stop. Instead, look up:

perldoc -f join
and
perldoc perlop (search for the $, and $" variables)

my $string = join(',', @array);
print "Values: $string\n";
# .... or....
{
local $, = ',';
print 'Values: ';
print @array;
print "\n";
}
#..... or ...
{
local $" = ',';
print "Values: @array\n";
}

Paul Lalli
 
J

Jürgen Exner

Jame said:
How can I remove any trailing commas from the end of $var?

I tried using

$var =~ s/,+$//

but it didn't work.

Works for me:

C:\tmp>type t.pl
use strict; use warnings;
my $var = 'foo,,,,';
print "$var\n";
$var =~ s/,+$//;
print "$var\n";
C:\tmp>t.pl
foo,,,,
foo

Maybe your $var does not contain what you think it contains?

jue
 
D

Dr.Ruud

Jame Pearl schreef:
How can I remove any trailing commas from the end of $var?
I tried using
$var =~ s/,+$//
but it didn't work.

If

$var =~ s/,+$//m;

does work, see `perldoc perlre` again.
 
G

Glenn Jackman

At 2006-01-30 06:16AM said:
How can I remove any trailing commas from the end of $var?

I tried using

$var =~ s/,+$//

but it didn't work.

Perhaps $var contains trailing whitespace. Try:
$var =~ s/,+\s+$//;
 
A

A. Sinan Unur

Dr.Ruud ([email protected]) wrote on MMMMDXXXV September MCMXCIII
in <URL:^^ Jame Pearl schreef:
^^
^^ > How can I remove any trailing commas from the end of $var?
^^ > I tried using
^^ > $var =~ s/,+$//
^^ > but it didn't work.
^^
^^ If
^^
^^ $var =~ s/,+$//m;
^^
^^ does work, see `perldoc perlre` again.


Hmmm.


$ perl -wle '$var = "foo,\nbar,"; $var =~ s/,$//m; print $var'
foo
bar,

This seals it for me. I have now been converted to the PBP recommendation
precisely which I can never remember what m and s modifiers do:

#!/usr/bin/perl

use strict;
use warnings;

my $var = "foo,\nbar,";
$var =~ s{ ,\z }{ }msx;
print "$var\n";

__END__

C:\Home\asu1\Perl> perl t.pl
foo,
bar
 
D

Dr.Ruud

Abigail schreef:
Dr.Ruud:

Hmmm.

$ perl -wle '$var = "foo,\nbar,"; $var =~ s/,$//m; print $var'
foo
bar,

That doesn't remove the comma at "the end".

If

$var =~ s/,+$//gm;

does even work better, then Jame's data is complexer than I was prepared
to assume.

Next episode:

$var =~ s/,+(?=\s*$)//;

(which also removes more than "trailing commas")


And s/,+(?=\s*)$// isn't the same, see perlre:
"two zero-width assertions next to each other work
as though they're ANDed together"
 
D

DJ Stunks

A. Sinan Unur said:
This seals it for me. I have now been converted to the PBP recommendation

The undead legions of Damian Conway's Perl Best Hacker Army welcome
you.

The rest of you be forewarned: resistance is futile; you will be
assimilated.

PBH #12011
-jp
 
U

Uri Guttman

DS> The undead legions of Damian Conway's Perl Best Hacker Army welcome
DS> you.

DS> The rest of you be forewarned: resistance is futile; you will be
DS> assimilated.

DS> PBH #12011
DS> -jp

i won't drink all of his koolaid! :) and i was a tech reviewer of
PBP. just that some of his ideas are for some people and not for
me. using \z is good and i will try to make that a habit but enabling /m
and /s all the time just bothers me as i like don't like to do things
with no technical purpose like that. i know what they mean just fine and
use them when i need to.

an important aspect of PBP is choosing which ideas will work for you and
then being consistant about using them. that is something i support and
practice.

uri
 
C

ced

This seals it for me. I have now been converted to the PBP recommendation
precisely which I can never remember what m and s modifiers do:

#!/usr/bin/perl

use strict;
use warnings;

my $var = "foo,\nbar,";
$var =~ s{ ,\z }{ }msx;
print "$var\n";

__END__

C:\Home\asu1\Perl> perl t.pl
foo,
bar

The OP didn't indicate whether $var might have a trailing newline
after the comma or not but you could handle both cases:


$var =~ s{ , (?: \z | \Z) }{ }msx;
 
J

John W. Krahn

Abigail said:
Uri Guttman ([email protected]) wrote on MMMMDXXXV September MCMXCIII
in <URL:~~
~~ i won't drink all of his koolaid! :) and i was a tech reviewer of
~~ PBP. just that some of his ideas are for some people and not for
~~ me. using \z is good and i will try to make that a habit but enabling /m
~~ and /s all the time just bothers me as i like don't like to do things
~~ with no technical purpose like that. i know what they mean just fine and
~~ use them when i need to.

I think that writing

s{ ,\z }{}xms

if you mean

s/,$//

is borderline idiocy.

If I wanted to be needlessly verbose, I would have written it in Java.

You don't have a COBOL compiler?


John
 
C

ced

Abigail said:
(e-mail address removed) ([email protected]) wrote on MMMMDXXXV
September MCMXCIII in <URL:""
"" > > ...
"" > > $ perl -wle '$var = "foo,\nbar,"; $var =~ s/,$//m; print $var'
"" > > foo
"" > > bar,
"" >
"" > This seals it for me. I have now been converted to the PBP recommendation
"" > precisely which I can never remember what m and s modifiers do:
"" >
"" > #!/usr/bin/perl
"" >
"" > use strict;
"" > use warnings;
"" >
"" > my $var = "foo,\nbar,";
"" > $var =~ s{ ,\z }{ }msx;
"" > print "$var\n";
"" >
"" > __END__
"" >
"" > C:\Home\asu1\Perl> perl t.pl
"" > foo,
"" > bar
""
"" The OP didn't indicate whether $var might have a trailing newline
"" after the comma or not but you could handle both cases:
"" $var =~ s{ , (?: \z | \Z) }{ }msx;

Why so difficult? $ already does that:


$ perl -wle '$var = "foo,"; $var =~ s/,$//; print "[$var]"'
[foo]
$ perl -wle '$var = "foo,\n"; $var =~ s/,$//; print "[$var]"'
[foo
]

I was thinking of a newline just before a trailing comma:

perl -e '$_ = "foo,\n,"; s{ , ( \z | \Z) }{}msx'' # result:
"foo,\n"

The alternation (\z|\Z) strips the trailing comma in "foo,\n," and
would strip
the comma in just "foo,\n" as well.

whereas:

$ perl -e '$_ = "foo,\n,"; s{,$}{}msx' # result: "foo\n,"

only picks up the leading comma.

And one of \z or \Z does that as well, matching at the end of the string,
or just before a final newline. But I can never remember which one does
so. $ OTOH, I won't forget.

Also note that your line replaces the comma with four spaces - not quite
the same as just removing the comma.

I see this mistake being made over and over again. /x only influences the
whitespace in the _pattern_. Whitespace in the replacement part remains
whitespace.

Yes, thanks. I mistakenly thought I saw a space in Sinan's
replacement { }
and figured he couldn't be wrong....:)
 
A

A. Sinan Unur

Abigail wrote:
....


Yes, thanks. I mistakenly thought I saw a space in Sinan's
replacement { } and figured he couldn't be wrong....:)

But you were not mistaken. There indeed was a space in the replacement,
and there should not have been.

The reason I like posting here is because I am frequently wrong, and
someone always corrects me in those cases.

Now, if you had said you thought Abigail could not be wrong, then you
would have a point.

Sinan
 
A

A. Sinan Unur

Uri Guttman ([email protected]) wrote on MMMMDXXXV September
MCMXCIII in <URL:~~
~~ i won't drink all of his koolaid! :) and i was a tech reviewer of
~~ PBP. just that some of his ideas are for some people and not for
~~ me. using \z is good and i will try to make that a habit but
enabling /m ~~ and /s all the time just bothers me as i like don't
like to do things ~~ with no technical purpose like that. i know what
they mean just fine and ~~ use them when i need to.

I think that writing

s{ ,\z }{}xms

if you mean

s/,$//

is borderline idiocy.

Well it is.

My response was to the following example you posted.


### $ perl -wle '$var = "foo,\nbar,"; $var =~ s/,$//m; print $var'
### foo
### bar,

In this case, I am presuming that one would want to remove the comma
after bar, and not the comma after foo.

So,

D:\> perl -wle "$var = qq{foo,\nbar,}; $var =~ s/,\z//m; print $var"
foo,
bar

or, as you pointed out, just leaving the m modifier would also do what
is intended:

D:\> perl -wle "$var = qq{foo,\nbar,}; $var =~ s/,$//; print $var"
foo,
bar

At this point, I realized that *I* always do have to look up the meaning
of the 'm' and 's' modifiers. And, that is when Damian Conway's advice
just seemed to make a lot of sense.
If I wanted to be needlessly verbose, I would have written it in Java.
;-)

Besides being concise, 's/,$//' has the advantage it works in 'sed'
and 'vi' as well. 's{ ,\z }{}xms' does not.

Good point.

Sinan
 
C

ced

Abigail said:
(e-mail address removed) ([email protected]) wrote on MMMMDXXXV
September MCMXCIII in <URL::)
:)
:) I was thinking of a newline just before a trailing comma:
:)
:) perl -e '$_ = "foo,\n,"; s{ , ( \z | \Z) }{}msx'' # result:
:) "foo,\n"
:)
:) The alternation (\z|\Z) strips the trailing comma in "foo,\n," and
:) would strip
:) the comma in just "foo,\n" as well.

But \Z does that as well:

$ perl -e '$_ = "foo,\n"; s{ ,\Z }{}msx;' # result: "foo\n"
$ perl -e '$_ = "foo,\n,"; s{ ,\Z }{}msx;' # result: "foo,\n"

:)
:) whereas:
:)
:) $ perl -e '$_ = "foo,\n,"; s{,$}{}msx' # result: "foo\n,"
:)
:) only picks up the leading comma.


Yeah, but the problem is the misuse of /m. Don't.

$ perl -e '$_ = "foo,\n"; s/,$//;' # result: "foo\n"
$ perl -e '$_ = "foo,\n,"; s/,$//;' # result: "foo,\n"


If you keep things simple, it just works.

Point taken. Any rote maneuver -- whether adding \m as a matter of
routine
or auto-pasting from a previous post, eg, { } on the substitution RHS
-- is
usually either a mistake or adds confusing, unnecessary complexity.

I still believe (\s|\S) -- without the unnecessary /ms -- is a
useful idiom here
to guarantee removal of the trailing character.
 
A

Anno Siegel

A. Sinan Unur said:
This seals it for me. I have now been converted to the PBP recommendation
precisely which I can never remember what m and s modifiers do:

Here is how I keep them apart:

/s stands for "single". It modifies the behavior of a single item,
namely ".". /m stands for "multiple". It modifies the behavior of
multiple (two) items, namely "^" and "$".

Anno
 
A

Anno Siegel

Uri Guttman said:
DS> The undead legions of Damian Conway's Perl Best Hacker Army welcome
DS> you.

DS> The rest of you be forewarned: resistance is futile; you will be
DS> assimilated.

DS> PBH #12011
DS> -jp

i won't drink all of his koolaid! :) and i was a tech reviewer of
PBP. just that some of his ideas are for some people and not for
me. using \z is good and i will try to make that a habit but enabling /m
and /s all the time just bothers me as i like don't like to do things
with no technical purpose like that. i know what they mean just fine and
use them when i need to.

an important aspect of PBP is choosing which ideas will work for you and
then being consistant about using them. that is something i support and
practice.

Me, I chose to do everything according to PBP I have been doing that
way all along. :)

The need for a strict style guide varies -- it is much stronger in a
team effort than in a one-man project. If I had to decide what language
to use in a big project (I don't and I won't), one thing I would look
for is a comprehensive style guide for the language to base my own on.
Perl now has that. That may have a long-term effect on the eligibility
of Perl for larger projects.

Anno
 
C

ced

Abigail said:
(e-mail address removed) ([email protected]) wrote on
MMMMDXXXVII September MCMXCIII in <URL:-:
-: I still believe (\s|\S) -- without the unnecessary /ms -- is a
-: useful idiom here
-: to guarantee removal of the trailing character.

[You mean (\z|\Z) here - as pointed out].

I disagree. I do not see the point of (\z|\Z). I don't think there's anything
that is matched by \z that isn't matched by \Z.

Your're right. \z just does half of what \Z does.
Could you give an example of a match (or substitution) where using '(\z|\Z)'
gives a different result from using '\Z'?

No :) Somehow I conflated \Z with something that matched only
before
a trailing newline. I've got it straight now..
 
C

ced

Your're right. \z just does half of what \Z does.

No :) Somehow I conflated \Z with something that matched only
before
a trailing newline. I've got it straight now..

A bit far fetched perhaps but, if you had a burning need to know where
the strip occurred:


if ( s{ , (?: (\z) | (\Z) ) }{}x ) {
print "stripped comma ", defined $1 ? "from end of string"
: "before
trailing newline";
}
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top