Re: cut of first char of a string
by Corion (Patriarch) on Mar 08, 2005 at 08:17 UTC
|
perl -pe "$_ = join '', splice @{[split //]}, 1"
| [reply] [d/l] |
|
| [reply] |
Re: cut of first char of a string
by sh1tn (Priest) on Mar 08, 2005 at 08:20 UTC
|
$_ = '12345'; $_ = join '',(split/^./);
| [reply] [d/l] |
|
Very nice++. I really like this one.
| [reply] [d/l] |
Re: cut of first char of a string
by davido (Cardinal) on Mar 08, 2005 at 08:19 UTC
|
# One way...
$s = join '', ( split //, $s )[ 1 .. length($s) - 1 ];
print $s, $/;
Update: And another.....
$s = pack 'A*', unpack( 'xA*', $s ); # ASCII only, please ;)
print $s, $/;
| [reply] [d/l] [select] |
|
$s = pack 'A*', unpack( 'xA*', $s ); # ASCII only, please ;)
I see no reason for the pack. And you're better of using 'a*' not 'A*', unless you really want to trim trailing spaces.
$s = unpack 'xa*', "qwerty ";
print "'$s'\n";
| [reply] [d/l] [select] |
Re: cut of first char of a string
by bart (Canon) on Mar 08, 2005 at 10:13 UTC
|
(undef, $s) = split //, $s, 2;
The 3rd parameter 2 makes split split into only 2 parts. I then simply ignore the first part.
| [reply] [d/l] |
|
Note that your solution makes $s undefined if $s was equal to the empty string. chop doesn't undef an empty string.
| [reply] |
Re: cut of first char of a string
by borisz (Canon) on Mar 08, 2005 at 08:38 UTC
|
$s = unpack "xA*", $s;
$s = substr($s, 1);
substr($s, 0, 1, "");
Update: remove wrong $s = in the last substr thanks to nothingmuch.
| [reply] [d/l] |
|
In the last one didn't you mean without $s =?
| [reply] [d/l] |
Re: cut of first char of a string
by chb (Deacon) on Mar 08, 2005 at 10:27 UTC
|
This uses a core module (and is Sick And Twisted(TM)):
use strict;
use warnings;
use Math::BigInt;
my $s = 'Hello World';
$s = reverse
((Math::BigInt->new('0b' .
(unpack('B*', $s) &
('00000000' .
('11111111' x (length($s) - 1))))))->as_bin())
+;
$s =~ s!b0!!;
$s = reverse(pack('b*', $s));
print "'", $s, "'\n";
| [reply] [d/l] |
Re: cut of first char of a string
by ambrus (Abbot) on Mar 08, 2005 at 12:08 UTC
|
There are an infinity of ways of course, but here are some.
substr($s, 0, 1, "");
substr($s, 0, 1) x= 0;
$s =~ /.(.*)/s and $s = $1;
open $s, "<", \$s; seek $s, 1, 0; local $/; $s = <$s>; # using no _add
+ittional_ vars
$s = substr $s, 1;
$s = substr $s, 1, ~0>>1, "JAPH";
$s=~s
s.sss;
Update 2006 apr 11.
Here is a list of other threads on choping the first character of strings; thanks to Limbic~Region for finding them.
If so many people want this, maybe we really need the chip/chimp functions in perl6?
Also, on substr($s, 0, 1) x= 0;, see substr() as an lvalue.
| [reply] [d/l] [select] |
|
| [reply] |
Re: cut off first char of a string
by Roy Johnson (Monsignor) on Mar 08, 2005 at 12:08 UTC
|
I haven't seen these posted yet:
($_) = /.(.*)/s;
# or
$_ = substr($_, -length($_)+1);
# or
/./s and $_ = $';
Caution: Contents may have been coded under pressure.
| [reply] [d/l] |
Re: cut of first char of a string
by rinceWind (Monsignor) on Mar 08, 2005 at 12:37 UTC
|
There's a whole aspect of this question which nobody has touched on yet. I'm talking about the precise meaning of "first char". Consider the situation when $s is a utf-8 string. The first "character" could be several bytes long.
This means that the regexp and chop methods will work on full "characters", but substr operates on "bytes".
I attended a talk recently at london.pm on this subject, the slides of which are here.
-- I'm Not Just Another Perl Hacker
| [reply] |
|
This means that the regexp and chop methods will work on full "characters", but substr operates on "bytes".
AFAIK unless the use bytes pragma is in effect substr operates on characters, not on bytes. Maybe the behaviour you describe is true pre 5.8.x but it isnt true in 5.8:
D:\Development>perl5.8.5 -le "my $str='ba'.pack('U',0x0370).'!'; print
+f qq'$_ : %d\n', ord(substr($str,$_,1)) for 0..length($str)-1"
0 : 98
1 : 97
2 : 880
3 : 33
D:\Development>perl5.8.5 -Mbytes -le "my $str='ba'.pack('U',0x0370).'!
+'; printf qq'$_ : %d\n', ord(substr($str,$_,1)) for 0..length($str)-1
+"
0 : 98
1 : 97
2 : 205
3 : 176
4 : 33
| [reply] [d/l] |
Re: cut of first char of a string
by Limbic~Region (Chancellor) on Mar 08, 2005 at 13:50 UTC
|
holli,
If we are just being silly:
$str = $_->[0] ? $str . $_->[1] : '' for map { [ $_, substr($str,$_,1)
+ ] } 0 .. length($str) - 1;
| [reply] [d/l] |
Re: cut of first char of a string
by japhy (Canon) on Mar 08, 2005 at 15:31 UTC
|
What a shame we can't write functions and what-not. I'd say the best way is to write an XS module that increments the SV's IV value, sets the OOK flag, and decrements its CUR value:
% perl -MDevel::Peek
$x = "japhy";
Dump($x);
$x =~ s/\C//;
Dump($x);
__END__
SV = PV(0x814ce90) at 0x81603ac
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x815d008 "japhy"\0
CUR = 5
LEN = 6
SV = PVIV(0x814d2a0) at 0x81603ac
REFCNT = 1
FLAGS = (POK,OOK,pPOK)
IV = 1 (OFFSET)
PV = 0x815d009 ( "j" . ) "aphy"\0
CUR = 4
LEN = 5
_____________________________________________________
Jeff japhy Pinyan,
P.L., P.M., P.O.D, X.S.:
Perl,
regex,
and perl
hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
| [reply] [d/l] |
Re: cut of first char of a string
by Anonymous Monk on Mar 08, 2005 at 08:51 UTC
|
Not necessary '^' metasym:
my $s = "123456789"; $s =~ s/.//
| [reply] [d/l] |
|
perl -MData::Dumper -e "$foo=qq(\nHello);$foo =~ s/.//; print Dumper \
+$foo"
Adding the /s flag makes dot match newline too:
perl -MData::Dumper -e "$foo=qq(\nHello);$foo =~ s/.//s; print Dumper
+\$foo"
| [reply] [d/l] [select] |
Re: cut of first char of a string
by TimToady (Parson) on Mar 10, 2005 at 08:41 UTC
|
Well, if you don't count $_ as an extra variable because it's already implicitly there, you can do it like this:
use bytes;
if (vec($s,3,2) < 3) {
vec($s,$_,8) = vec($s,$_+1,8) for 0..length($s)-2;
chop($s);
}
else {
vec($s,$_,8) = vec($s,$_+1,8) for 0..length($s)-2;
chop($s);
while (vec($s,3,2) == 2) {
vec($s,$_,8) = vec($s,$_+1,8) for 0..length($s)-2;
chop($s);
}
}
Update:
Hmm, here's a solution without $_:
use bytes;
if (vec($s,3,2) < 3) {
() = $s =~ m/.(?=.)(?{ vec($s,pos($s)-1,8) = vec($s,pos($s),8)
+})/sg;
chop($s);
}
else {
() = $s =~ m/.(?=.)(?{ vec($s,pos($s)-1,8) = vec($s,pos($s),8)
+})/sg;
chop($s);
while (vec($s,3,2) == 2) {
() = $s =~ m/.(?=.)(?{ vec($s,pos($s)-1,8) = vec($s,pos($s
+),8)})/sg;
chop($s);
}
}
| [reply] [d/l] [select] |
Re: cut of first char of a string
by cog (Parson) on Mar 08, 2005 at 10:42 UTC
|
$s =~ s/^.//;
print "$s\n";
Could be written as:
$s =~ s/.//;
print "$s\n";
Update: I had assumed the string would only contain the regular \w characters; won't work for strings starting with \n, obviously (because the dot doesn't match newlines). See Re: cut of first char of a string. | [reply] [d/l] [select] |
Re: cut of first char of a string
by jbrugger (Parson) on Mar 08, 2005 at 09:46 UTC
|
#!/bin/perl
use strict;
my $s = "Hello world!";
print substr($s,1,length($s));
| [reply] [d/l] |
Re: cut of first char of a string
by Anonymous Monk on Mar 08, 2005 at 10:25 UTC
|
Some variations on four themes: substr($s, 0, 1, ""), $s =~ s/.//s;, and use of split and unpack.
$s = (split /./s, $s, 2)[1] err ""; # Needs 'defined-or' patch, or 5.9
+.1
$s = (split /./s, $s, 2)[1]; $s = "" unless defined $s;
$s = length $s ? (split /./s, $s, 2)[1] : "";
$s = join "", map {substr $s, $_, 1} grep {$_} 0 .. length($s)-1;
substr $s, $_, 1, $_ ? substr($s, $_, 1) : "" for 0 .. length($s)-1;
local $a = 0; $s = join "", grep {$a++} split //, $s;
local $" = ""; $s = "@{[(split //, $s)[1 .. length($s)-1]]}
$s =~ s/(?<!.).//sg;
local $a; $s =~ s/.(??{$a++ ? "(?!)" : "(?=)"})//sg;
$s = pack "A*", (unpack "A*", $s)[1 .. length($s)-1];
$s = pack "A*", unpack "xA*", $s if length $s;
$s = pack "A*", unpack "xA@{[length($s)-1]}", $s if length $s;
| [reply] [d/l] [select] |
Re: cut of first char of a string
by sh1tn (Priest) on Mar 08, 2005 at 12:24 UTC
|
$_ = '12345';s/(.(.*))/$2or$1/e
| [reply] [d/l] |
|
That doesn't work correctly:
perl -wle '$_ = '10'; s/(.(.*))/$2or$1/e; print'
10
| [reply] [d/l] |
|
Yes, that doesn't, but this does:
s/(.(.*))/($2ne'')?$2:$1/e
| [reply] [d/l] |
|
|
Re: cut of first char of a string
by blazar (Canon) on Mar 08, 2005 at 13:10 UTC
|
How many ways How many ways does Perl have to cut off the first char of a string?
At a first glance it seems that this has not been mentioned yet, although basically it may be thought of as a variation of several of those that have been:
$ perl -lne 'print for /(.)(.*)/'
dfdfsdgdfs
d
fdfsdgdfs
stgsghttsthe
s
tgsghttsthe
| [reply] [d/l] |
Re: cut of first char of a string
by eisforian (Novice) on Mar 08, 2005 at 15:31 UTC
|
$s = "12345678";
$s = join '', ( split //, $s )[
(
sprintf( '%03d%03d', length($s), length($s) ) / 7 / 11 / 13 -
sprintf( '%03d', length($s) ) + 1 ) .. length($s) - 1
];
print "$s\n";
| [reply] [d/l] |
Re: cut of first char of a string
by Joost (Canon) on Mar 08, 2005 at 15:58 UTC
|
use Symbol;
my $s = "123456789";
Symbol::qualify_to_ref"s::".reverse$s&"\0".("\xff"x length$s);
$s=reverse keys %s::;
| [reply] [d/l] |
Re: cut of first char of a string
by Jasper (Chaplain) on Mar 08, 2005 at 15:46 UTC
|
$_ = $' x /./
edit: damn, I see Roy already had this (effectively) | [reply] [d/l] |
Re: cut of first char of a string
by calin (Deacon) on Mar 08, 2005 at 16:57 UTC
|
This does not exactly meet your requirements (no additional vars), but since everybody is going for crazy solutions and I have time to kill, here it is:
use v5.8;
$s = "abcdef"; # or initialize it yourself
($s, $_) = (undef, $s);
$s.=???!??:$&while/./g;
print "$s\n";
Warning: Does not work correctly under Perls earlier than 5.8 (change in semantics). It can be fixed though, at the expense of aesthetics.
| [reply] [d/l] |
Re: cut of first char of a string
by Anonymous Monk on Mar 08, 2005 at 17:17 UTC
|
How many ways does Perl have to cut off the first char of a string?
An infinite number, of course.
For example, there are an infinite number of variations of the following solution:
Append a string known not to be within the string, move the first character after the unique tag, then remove everything after the unique tag.
You can increase the length of the unique tag string towards infinity, and you'll get an infinite number of solutions.
--
Ytrew | [reply] |
|
$_ = '12345';$_ = join'',(@{[split//]}[1..@{[split//]}]) # ?
| [reply] [d/l] |
Re: cut of first char of a string
by Whitehawke (Pilgrim) on Mar 12, 2005 at 05:56 UTC
|
Well, here's a couple of simple ones:
print join'',@{[do{shift@{$s=[split//,$s='foobarbaz']};@$s}]}
print $s=reverse@{$s=do{pop @{$s=[split//,reverse$s='foobarbaz']};$s}}
Although, I'm honestly not sure why the $s= that immediately precedes the do is necessary in the second one. Can anyone explain it to me?
| [reply] [d/l] [select] |
|
I'm not sure but I think it's needed because you assign an anonymous array to $s before it, so if you do not set $s, the rightmost $s will give that array.
| [reply] [d/l] [select] |
Re: cut of first char of a string
by sh1tn (Priest) on Mar 10, 2005 at 06:43 UTC
|
$_='0123456789'
;s;.(?=(.+));$1;s&&s;(.+)(\1);$1;s;
| [reply] [d/l] |