Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Look behind and global

by gingaloon (Acolyte)
on Mar 14, 2005 at 11:40 UTC ( [id://439231]=perlquestion: print w/replies, xml ) Need Help??

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

Dear All, I wish to insert a new line every two digits. Thought I'd use look-behind to do this:
my $x=12345; $x=~s/(?<=\d{2})/\012/g; print $x,"\n";
I get:
12
3
4
5
I know I can do this other ways, but the result has left me confused as to what is going on with the look behind with the global modifier. Surely at position 3 the look behind 'sees' 12\n? No? Any explanation would be appreciated many thanks james

Replies are listed 'Best First'.
Re: Look behind and global
by hv (Prior) on Mar 14, 2005 at 11:55 UTC

    When performing s///g substitutions, the regexp engine does all the matching on the original unaltered string, and makes a copy on which to perform all the substitutions. So in this case, all the matches are looking at "12345", and at each position from offset 2 onwards it successfully finds that it is "just after two digits".

    In this case, the simplest way to achieve the desired effect is to have the digits be part of the match rather than perceived only as part of a zero-width assertion:

    $x =~ s/(\d{2})/$1\n/g;

    Hugo

Re: Look behind and global
by maa (Pilgrim) on Mar 14, 2005 at 11:51 UTC

    Hi gingaloon

    if you have 12345 then the sequences of two digits are 12 23 34 45...

    HTH - Mark

    Update: my (guessed) explanation as to why you don't get what you want is that you're not modifying the pattern "in-place", so to speak, so the regexp engine doesn't take account of the changes it makes. This is one use for backreferences (\1 \2 \3)

    Update 2: why not just s/(\d\d)/$1\n/g?

Re: Look behind and global
by thinker (Parson) on Mar 14, 2005 at 12:03 UTC

    In the spirit of TIMTOWTDI, you could do this

    print map "$_\n", $x =~ /..?/g ; 12 34 5

    cheers

    thinker

Re: Look behind and global
by Tanktalus (Canon) on Mar 14, 2005 at 15:31 UTC

    The only nice thing about zero-width assertions is that you don't have to capture anything. So, in that spirit, and in the spirit of TMTOWTDI, and in the spirit that this is what you were asking about (whether it's the best way to do it or not):

    $ perl -e '$x=12345; $x=~s/(?<=\G\d{2})/\012/g; print $x,$/' 12 34 5
    As you can see - I just added the \G to the assertion. Of course, if you start using anything other than numbers in there, I'm sure this could get all mucked up:
    $ perl -e '$x="123d45"; $x=~s/(?<=\G\d{2})/\012/g; print $x,$/' 12 3d45

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://439231]
Approved by virtualsue
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-24 11:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found