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

hi monks,

i have a text which have more than 300 characters (for example ) and i want to split it every 70 characters

alone only if it's not already splited i mean text example

hiiiiiiiiiiiiiiiiiihiiiiiiiiiiiiiiiiii hiiiiiiiiiiiiiiiiiihiiiiiiiiiiiiiiiiii hiiiiiiiiiiiiiiiiiihiiiiiiiiiiiiiiiiii

this one was splited , if it wasn't it would take up all the screen and this is my problem

i cant think of any idea that can help me out

can you help?

thanks in advance

Replies are listed 'Best First'.
Re: spliting text!!
by duff (Parson) on Mar 08, 2007 at 19:04 UTC
    This will chop up your string into chunks that are a maximum of 70 characters, if that's what you're looking for.
    my @array = $string =~ /.{1,70}/gs; # Maybe?
    There are other solutions using unpack() and substr() and the like too if those are more to your understanding.
Re: spliting text!!
by imp (Priest) on Mar 08, 2007 at 19:10 UTC
    use strict; use warnings; my $line = <DATA>; # Quick and dirty # Greedily match anything from 1-70 characters my @lines = $line =~ /.{1,70}/g; print $_,"\n" for @lines; # Less memory use for large blocks of text while ($line =~ /(.{1,70})/g) { print $1,"\n"; } __DATA__ 1234567890123456789012345678901234567890123456789012345678901234567890 +123456789012345678901234567890123456789012345678901234567890123456789 +012345678901234567890123456789012345678901234567890123456789012345678 +901234567890123456789012345678901234567890123456789012345678901234567 +890123456789012345678901

      Just because I'm mildly annoyed at the width of your code, how about, instead of reading from the DATA file handle you do something like this:

      my $line = '1234567890' x 20;
      BTW, you may want to use /s on your pattern so that . matches any character since we don't know the exact contents of the OP's strings.

      cheers,

        If the code isn't wrapping you can goto "Display Settings" and uncheck 'Code Wrapping Off' so that perlmonks will wrap the code up for you. Just an FYI in case you (or someone else reading) didn't know.


        ___________
        Eric Hodges
Re: spliting text!!
by ikegami (Patriarch) on Mar 08, 2007 at 18:55 UTC

    Text::Wrap? (Never used it)

    It breaks where there's a space if possible, but it'll break long words too.

      I used Text::Wrap to display a list of quotations stored in a database. Sample code looks like:
      #! /usr/bin/perl -w use strict; use Text::Wrap; my $quote = { ID => 308 , Author => "Someone" , Quote => "123456789_" x 10 }; local $Text::Wrap::columns = 71; # from (70 + 1) where 70 is the max +width print "\nQuote Number " . $quote->{"ID"} . ":\n" . wrap('', '', $quote->{"Quote"}) . "\n" . " - " . $quote->{"Author"} . "\n\n";
      The output is:
      Quote Number 308: 123456789_123456789_123456789_123456789_123456789_123456789_123456789_ 123456789_123456789_123456789_ - Someone
Re: spliting text!!
by Herkum (Parson) on Mar 08, 2007 at 18:58 UTC
    my $text = s{(\S{70})}{\1 }g;

    This will add a space every 70 characters.

    Update: Sorry I misread your question, did you what to split your string into an array or did you just want to space out a very long string?

      Using \1 in s/// is depreciated as it can be ambiguously interpreted as a charachter since the second half of the substitution is treated as a quoted string; just use $1.

Re: spliting text!!
by swampyankee (Parson) on Mar 09, 2007 at 00:04 UTC

    This could be a job for split!

    use strict; use warnings; my $string = 'abcdef123456' x 20; my @array = split(/(.){70}/, $string); @array = grep { defined } @array;

    Note: Code is not tested

    emc

    Insisting on perfect safety is for people who don't have the balls to live in the real world.

    —Mary Shafer, NASA Dryden Flight Research Center
      Note: Code is not tested

      Here's a way to test it:

      $ perl -le '$s="1234567890"x20;@s=split(/(.){70}/,$s); print length($s);print scalar @s;print join("\n",@s)' 200 5 0 0 123456789012345678901234567890123456789012345678901234567890
      I'm not sure how to explain that output (5 array elements, first and third are empty strings, second and fourth are "0", fifth is 60 characters), but part of the reason might be evident from a slight change -- put the capturing close-paren after the "{70}":
      $ perl -le '$s="1234567890"x20;@s=split(/(.{70})/,$s); print length($s);print scalar @s;print join("\n",@s)' 200 5 1234567890123456789012345678901234567890123456789012345678901234567890 1234567890123456789012345678901234567890123456789012345678901234567890 123456789012345678901234567890123456789012345678901234567890
      That's a little better, but not quite what the OP was looking for, I think. Hard to be sure exactly what the OP was looking for, but having the first and third array elements empty (again) is probably not part of the plan.

      The first element is empty because an empty string "occurs before" the first string that matches the split regex. The second array element is the part that matched the split regex (because of the parens). The third is empty, because that's what occurs before the split regex matches again. Fourth element is the second string to match the split regex. Last element is the remainder (split regex didn't match anymore).

      Maybe you meant something like:

      split /(?<=.{70})(.{70})/ # pos.look-behind for 70 chars, then captur +e 70
      (updated to fix incorrect comment)

      Let's test that:

      $ perl -le '$s="1234567890"x20;@s=split(/(?<=.{70})(.{70})/,$s); print length($s);print scalar @s;print join("\n",@s)' 200 3 1234567890123456789012345678901234567890123456789012345678901234567890 1234567890123456789012345678901234567890123456789012345678901234567890 123456789012345678901234567890123456789012345678901234567890
      I'm not sure if that's a "better" solution than what other monks have proposed above, but it seems to work. ;)

      Actually, IMHO, this is almost a perfect example of when not to use split. :-)

Re: spliting text!!
by Anonymous Monk on Mar 09, 2007 at 14:33 UTC
    thanks for your help ;)