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

Hello fellow monks, I call upon your wisdom to help me with this task.
I have the following string.
my $owners = 'Shaun Anderson,Salve Barnao,James Clark,John Cross,Bruce + Jenkins,George Kelly,Danny Phipps & Robert Rendel';
This string is dynamic with the number of owners varying from 1 to many. I am wanting to split this string if its longer than say 45 characters. I want to split on the ',' that seperates each owner. eg
my $owners1 = 'Shaun Anderson,Salve Barnao,James Clark,John Cross,'; my $owners2 = 'Bruce Jenkins,George Kelly,Danny Phipps & Robert Rendel +';
Therefore it may be slightly less than 45 characters but that would be ok. This line of code is used in producing horse racebooks. Rather than having one line that is too long, I want to split it into 2 or 3 lines depending on the number of owners.
Thankyou very much, Digger

2005-10-02 Retitled by planetscape, as per Monastery guidelines
Original title: 'Split on character length'

Replies are listed 'Best First'.
Re: Split on field length
by japhy (Canon) on Sep 28, 2005 at 21:18 UTC
    The general technique here is @parts = $string =~ /(.{1,44}(?:,|$))/g; You get chunks of up to 45 characters, ending either with a comma or at the end of the string. If there's a possibility of newlines in your data, just add the /s modifier to the regex.

    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
      Of course, if a name is longer than 45 char's this will silently eat the start of that name. Im not sure if its at all possible to handle this nicely with a regexp, at least I have never managed to do it. Problems is how to handle the case where you cant break the input the way you want.

      Now, it wasn't really specified how to handle this situation, maybe break on whitespace instead? Or just simply overflow? (One application I work with frequently will hang forever trying to break a line longer than 80 characters if there are no spaces in it:-). Anyway, if overflowing is the solution for this particular problem, then Text::Wrap might come to the rescue:

      use Text::Wrap qw(wrap); my @parts=do { local $Text::Wrap::columns=45; local $Text::Wrap::huge='overflow'; local $Text::Wrap::separator=",\n"; local $Text::Wrap::break=qr/\s*,\s*/; split /\n/, wrap('','',$string); };
      gc
Re: Split on field length
by ioannis (Abbot) on Sep 29, 2005 at 01:47 UTC
    And here is another way:
    ($owners =pack ('A45', $owners)) =~ s/ [^,]*? $//x;
Re: Split on field length
by Zaxo (Archbishop) on Sep 29, 2005 at 12:26 UTC

    Yet another way.

    my $owners = "Shaun Anderson,Salve Barnao,James Clark,John Cross,Bruce + Jenkins,George Kelly,Danny Phipps & Robert Rendel"; my @owners; push @owners, substr( $owners, 0, 1+rindex($owners,",",45), "") while 45 < length $owners; push @owners, $owners; print $_, $/ for @owners;' __END__ 123456789012345678901234567890123456789012345 Shaun Anderson,Salve Barnao,James Clark, John Cross,Bruce Jenkins,George Kelly, Danny Phipps & Robert Rendel

    After Compline,
    Zaxo

      This is the way of doing it that hangs forever if a name is longer than 45 char's:-)

      gc

Re: Split on field length
by Anonymous Monk on Sep 28, 2005 at 21:41 UTC
    Worked perfectly. Thankyou soo much. Very fast response and clever answer. :)