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

Hey Monks
I have a string which I want to add a newline after the first 39 characters (as long as its not in the middle of a word) and then add a newline every 60 characers. I am able to successfully do it, however I'm sure there is much cleaner way. Any suggestions would be appreciated.
use strict; use warnings; my $t = "Call me a joker call me a fool. Right at this moment Im tota +lly cool. Clear as a crystal, sharp as a knife. I feel like Im in t +he prime of my life. Sometimes it feels like I'm going to fast. I d +ont know how long this feeling will last. Maybe its only tomihgt."; my ($string, $i); my $s = length $t; if ($s > 39){ my $i = 39; while ($i < $s){ if ($i == 39){ $i = index($t," ", $i); $string = substr($t, 0, $i); print $string; } else{ my $i2 = index($t, " ", $i+60); if ($i2 == -1){ my $end = substr($t, $i, $s); $end =~s/^\s+//; $string .= "\n" . $end; last; } else{ print $i . " " . $i2 . "\n"; my $end = substr($t, $i, $i2-$i); $end =~s/^\s+//; $string .= "\n" . $end; $i = $i2; } } } } print $string;

Replies are listed 'Best First'.
Re: adding newline to middle of a string cleanly
by Roy Johnson (Monsignor) on Dec 09, 2003 at 21:42 UTC
    If you want to wrap text, there are modules, such as Text::Wrap.

    For your particular example, is it supposed to be wrap at the first whitespace after the 39th character, and then at the first whitespace after the 60th character of each subsequent line?


    The PerlMonk tr/// Advocate
Re: adding newline to middle of a string cleanly
by Roger (Parson) on Dec 09, 2003 at 22:20 UTC
    I have posted a one liner to do text wrapping earlier, which you could give it a try.
    $text =~ s/(.{30,40}(?<=\s\b))/$1\n/mg;
    Also I highly recommend the module Text::Autoformat from CPAN that does a great job at text wrapping, justification, etc.
    use Text::Autoformat qw(autoformat); $newtext = autoformat($text, { left=>1, right=>40, all=>1 });
Re: adding newline to middle of a string cleanly
by Roy Johnson (Monsignor) on Dec 09, 2003 at 21:53 UTC
    Me again. Does this do what you want?
    $t =~ s/(.{39}[^\s]*)\s+/$1\n/; $t =~ s/([^\n]{60}[^\s]*)\s+/$1\n/g;
    Update: removed unnecessary parens. I don't know what I was thinking when I put them in.

    The PerlMonk tr/// Advocate
      Thanks Roy...exactly what I was looking for.
Re: adding newline to middle of a string cleanly
by Sandy (Curate) on Dec 10, 2003 at 01:06 UTC
    This works, ... if the number of characters per line is a maximum.

    I'm not sure if it is optimized for flipping from the 36 characters/line to 60 characters/line.

    \#!/usr/bin/perl my $par = "Call me a joker call me a fool. Right at this moment Im to +tally cool. Clear as a crystal, sharp as a knife. I feel like Im in + the prime of my life. Sometimes it feels like I'm going to fast. I + dont know how long this feeling will last. Maybe its only tomihgt." +; my $text; # insert some new-lines to make text easier to read (my @words) = split /( )/,$par; my $char = 0; my $line_length = 36; foreach my $word (@words) { $char += length $word; if ($char > $line_length ) { $text .= "\n"; $char = length $word; $line_length = 60;} $text .= $word; } print $text,"\n";
Re: adding newline to middle of a string cleanly
by Sandy (Curate) on Dec 10, 2003 at 01:12 UTC
    PS: I like the 1st three replies better than my own...

    should read stuff before i type

    sigh...

    Question: Is regex's faster or slower than brute force??

    Unfortunately, I don't have time right now to test it, but I will.