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

Hi all.
There is a simple task: parse a long string to readable format.
only two main rules:
1. string must be less than 15 chracters before \n
2. put \n after comma if it is possible

it can be done using cicle of course:
my $data = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,".('c'x50).",16,17,1 +8,19,20,21,22,23,24,25,26,27"; while ($data =~/[^\n]{16}/) { $data =~s/([^\n]{16})/ch($1)/e; } print $data; sub ch { my $s = shift; my $p = rindex($s, ',', 14)+1; $p=15 unless($p); return substr($s, 0, $p)."\n".substr($s, $p) };
or with help of recursion function, but i want try to do it using executable regexp with g option (instead of while).
$data =~s/([^\n]{16})/ch($1)/ge;
but in with case result is wrong, because tail of previous result concatinates with head of new. To escape with situation we must to change current search position in regexp to earlier value (even if we set 0 it's ok). Pos() function allow to change search position in regexp, but it seems it can't be use inside of regexp itself.
With variant is nothing changes
$data =~s/([^\n]{16})/pos($data)=0;ch($1)/ge;
So my question is: Is it possible change search position from regexp itself?

Replies are listed 'Best First'.
Re: Using pos() inside regexp (no /e)
by tye (Sage) on Oct 08, 2010 at 05:37 UTC
    s/([^\n]{0,14},|[^\n]{15})(?=[^\n])/$1\n/g

    - tye        

      Ups, your solution is much better than mine, thanks a large. There is a small problem with last line in that case so i think better to use something like
      s/((?:[^\n]{0,15}$)|(?:[^\n]{0,14},)|(?:[^\n]{15})(?=[^\n]))/$1\n/g;
      nevertheless it's interesting to know is it possible to use pos() function to set search position inside of regexp, or it works outside only.
        If I'm reading that correctly, you want a newline at the end? If so, the following will do:
        # Adds trailing newline s/([^\n]{0,14},|[^\n]{15})(?!\n)/$1\n/g
        Compare with tye's:
        # Doesn't add trailing newline s/([^\n]{0,14},|[^\n]{15})(?=[^\n])/$1\n/g
        No. The pos() works only outside of matching. It works with the position where the matching operation has stopped. During matching this function does not make sense. \G references the position from the previous matching.