Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I want to format a string so that it neatly prints 60 characters per line. The only way I know how to do this is with:
$string =~ s/(.{60})/$1\n/g;
However, i want to do this in a loop where $1 is already being used as something else, hence this doesn't work! Can anyone suggest an alternative?? Thanks!
if ($line =~ /^\s{0,3}(\w+)(\d+)(\w+)\s+((\w+))/) { # $1-$3 used by something else here my $string = $4; $string =~ s/(.{60})/$1\n/g; print "$string\n"; }

Replies are listed 'Best First'.
Re: formatting strings
by borisz (Canon) on Jan 05, 2005 at 11:10 UTC
    You can use Text::Wrap, Text::Format, Text::Autoformat or whatever from CPAN.
    Or use your peace of code and assign the $1, $2,... to something else.
    if ($line =~ /^\s{0,3}(\w+)(\d+)(\w+)\s+((\w+))/) { my ( $ws1, $num, $ws2, $string ) = ( $1, $2, $3, $5 ); $string =~ s/(.{60})/$1\n/g; print "$string\n"; }
    Boris
Re: formatting strings
by ysth (Canon) on Jan 05, 2005 at 11:01 UTC
    if ($line =~ /^\s{0,3}(\w+)(\d+)(\w+)\s+((\w+))/) { # $1-$3 used by something else here my $string = $4; { $string =~ s/(.{60})/$1\n/g; } print "$string\n"; }
    Putting a block around it isolates the change to $1 to within that block. After the block ends, $1 will regain its previous value.

    But you might be better off saving the captured items to variables right away:

    if (my ($word1, $number, $word2, $string) = $line =~ /^\s{0,3}(\w+)(\d+)(\w+)\s+((\w+))/) { # $word1, $number, and $word2 used by something here $string =~ s/(.{60})/$1\n/g; print "$string\n"; }
Re: formatting strings
by pelagic (Priest) on Jan 05, 2005 at 11:05 UTC
    Have a look at printf to just format the printing and not the string.

    pelagic

      Or sprintf if you really want to format just the string for some reason.

      Anima Legato
      .oO all things connect through the motion of the mind

Re: formatting strings
by thor (Priest) on Jan 05, 2005 at 11:54 UTC
    No claims on efficiency, but
    print join("\n", unpack("(A60)*", $string)"
    should do the trick. This also assumes a semi-recent perl (I think this feature came about sometime in 5.8).

    thor

    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    For all of us waiting, your kingdom will come

Re: formatting strings
by ikegami (Patriarch) on Jan 05, 2005 at 17:31 UTC

    I wrote a snippet for someone a while back. It wraps without truncating words. While it doesn't help you preserve $1 (which you could do by copying $1 into a different variable), I thought you might find it useful.

    sub line_wrap { my ($str, $max) = @_; my @lines; foreach my $line (split($\, $str)) { # # Collapse spaces and tabs. # s/\s+/ /g; while (length($line) > $max) { my $max2 = $max - 1; if ($line =~ s/^(.{0,$max2}\S)\s+//s) { # Break at space. push(@lines, $1); } else { # No space. $line =~ s/^(.{$max})//s; push(@lines, $1); } } push(@lines, $line); } return join($\, @lines) . $\; }

    Known Bugs: Counts tabs as one char, and only does line breaks at a space.