Re: fixed length string
by edan (Curate) on Jul 05, 2004 at 09:45 UTC
|
my $fixed = sprintf "%-5.5s", $string;
| [reply] [d/l] |
Re: fixed length string
by muntfish (Chaplain) on Jul 05, 2004 at 09:44 UTC
|
Perl doesn't have a data type with that behaviour, but you could try something like:
use strict;
my ($len, $str) = (5, "someword");
$str = sprintf "%-${len}.${len}s", $str;
print ">>$str<<\n";
s^^unp(;75N=&9I<V@`ack(u,^;s|\(.+\`|"$`$'\"$&\"\)"|ee;/m.+h/&&print$&;
| [reply] [d/l] [select] |
Re: fixed length string
by BrowserUk (Patriarch) on Jul 05, 2004 at 10:46 UTC
|
print "'", pack( 'A5', $_ ), "'" for qw[ so some somewhat ];
'so '
'some '
'somew'
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
| [reply] [d/l] |
|
|
Pack truncates as well as pads. (Mental note: caffeinate before posting.)
Rate srchrep xprintf YAW
srchrep 5434/s -- -79% -82%
xprintf 25870/s 376% -- -16%
YAW 30876/s 468% 19% --
| [reply] [d/l] |
Re: fixed length string
by keszler (Priest) on Jul 05, 2004 at 10:05 UTC
|
s/// can do the job: use .{1,$x} to get the first 1 to $x characters, discarding any after $x, then pack "A$x" to space-pad to $x.
#!perl
use strict;
my $fixlen = 5;
my @words = qw( s so som some somew somewo somewor someword somewords)
+;
foreach my $word (@words) {
$word =~ s/^(.{1,$fixlen}).*$/pack "A$fixlen", $1/e;
print ">$word<\n";
}
__END__
>s <
>so <
>som <
>some <
>somew<
>somew<
>somew<
>somew<
>somew<
| [reply] [d/l] |
|
|
I was curious, so I compared the two one-liners (s/// and sprintf), as follows:
#!perl
use strict;
use Benchmark qw( timethese cmpthese ) ;
my $fixlen = 5;
my @words = qw( s so som some somew somewo somewor someword somewords)
+;
my $b = timethese( -5, {
srchrep => sub{foreach my $word (@words) {
$word =~ s/^(.{1,$fixlen}).*$/pack "A$fixlen", $1/e
+;
}},
xprintf => sub{foreach my $word (@words) {
$word = sprintf "%-$fixlen.${fixlen}s", $word;
}},
});
cmpthese $b;
__END__
Benchmark: running srchrep, xprintf for at least 5 CPU seconds...
srchrep: 5 wallclock secs ( 5.54 usr + 0.00 sys = 5.54 CPU) @ 54
+48.01/s (n=30182)
xprintf: 6 wallclock secs ( 6.76 usr + 0.00 sys = 6.76 CPU) @ 20
+874.11/s (n=141109)
Rate srchrep xprintf
srchrep 5448/s -- -74%
xprintf 20874/s 283% --
Looks like sprintf wins the speed test, by a large margin.
| [reply] [d/l] |
|
|
my $str = 'somewords';
local ($\,$,) = ("\n") x 2;
print map {substr $str, 0, $_} 1..length($str);
# or
print map {$str =~ /(.{$_})/} 1..length($str);
# or
{
my $mem;
print map {$mem .= $_} split //, $str;
}
# etc. (Golf?)
| [reply] [d/l] [select] |
Re: fixed length string
by gellyfish (Monsignor) on Jul 05, 2004 at 13:44 UTC
|
As has been pointed out perl does not natively have a fixed length datatype - but it is easy to do something that make a scalar behave like that:
FixedLength.pm:
package FixedLength;
use strict;
use warnings;
sub TIESCALAR
{
my ( $class, $length) = @_;
my $self = {};
$self->{_item} = undef;
$self->{_length} = $length;
return bless \$self, $class;
}
sub FETCH
{
my ($self) = @_;
return $$self->{_item};
}
sub STORE
{
my ( $self, $value ) = @_;
my $len = $$self->{_length};
$$self->{_item} = pack "A$len", $value;
}
1;
Test Code:
use FixedLength;
use strict;
my $foo;
tie $foo, 'FixedLength', 5;
my @words = qw( s so som some somew somewo somewor someword somewords)
+;
foreach my $word ( @words)
{
$foo = $word;
print "*$foo*\n";
}
/J\ | [reply] [d/l] [select] |
Re: fixed length string
by borisz (Canon) on Jul 05, 2004 at 09:49 UTC
|
You can use substr to get parts of your string and the x operator to add missing parts.
my $max = 10;
my $string = 'something';
$string = substr($string, 0, $max);
my $length = length $string;
$string .= ' ' x ( $max - $length ) if ( $length < $max );
| [reply] [d/l] [select] |
Re: fixed length string
by Crian (Curate) on Jul 05, 2004 at 09:43 UTC
|
You could use a function like this:
#!/usr/bin/perl
use strict;
use warnings;
sub cut_fill ($$);
my $word = 'someword';
print "'", cut_fill($word, 5), "'\n";
print "'", cut_fill($word, 10), "'\n";
sub cut_fill ($$) {
my ($word, $length) = @_;
if (length($word) >= $length) {
$word = substr($word, 0, $length);
}
else {
$word .= ' 'x($length - length($word));
}
return $word;
}
Update: Or you can use sprintf of corse, as shown in the solutions below. But if you need something more special, a function like this will be handy. | [reply] [d/l] |
Re: fixed length string
by gmpassos (Priest) on Jul 06, 2004 at 07:02 UTC
|
How about one line, ops, one command?! ;-P
$s = sprintf("%-5.5s" , $s) ;
Graciliano M. P.
"Creativity is the expression of the liberty".
| [reply] [d/l] |