Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

rotate a vector with a regex?

by misterperl (Acolyte)
on Nov 20, 2012 at 21:46 UTC ( #1004804=perlquestion: print w/ replies, xml ) Need Help??
misterperl has asked for the wisdom of the Perl Monks concerning the following question:

Say I'd like to move the first char in a string to the other end. An obvious choice might be

s/(.)(.+)/$2$1/

But I wondered- what if I tried to move it pairwise along the string (bubble it). It seems like as long as I could get the matching position to move by 1, instead of 2, I could do it that way. Just for academic reasons I wondered..

It seems like something along these lines, with the positive lookhead, could potentially bubble the char:

s/(.)(?=.)/$2$1/g;

which I'd hoped would perform these steps: 12345
21345
23145
23415
23451


but instead it produced 5 warnings and left the string unchanged (I presume the warnings were that $2 was undef)..

Thoughts, wondrous monks?

Comment on rotate a vector with a regex?
Re: rotate a vector with a regex?
by frozenwithjoy (Curate) on Nov 20, 2012 at 22:00 UTC
    Are you interested in the end product or do you want all intermediates?

    This will give you the end product:

    #!/usr/bin/env perl use strict; use warnings; use feature 'say'; my $string = "12345"; $string = substr( $string, 1 ) . substr( $string, 0, 1 ); say $string; __END__ 23451

    EDIT: Just realized you were asking for something else. Oops. I think AnomalousMonk is correct about it not being possible this way. Regarding the errors, you need to specify the second capture group since the second set of parentheses you have are part of the lookahead. This gets rid of the warnings:

    $ perl -WE '$string = "12345"; $string =~ s/(.)(?=(.))/$2$1/g; say $st +ring' 213243545
Re: rotate a vector with a regex?
by AnomalousMonk (Abbot) on Nov 20, 2012 at 22:08 UTC
    s/(.)(?=.)/$2$1/g;
    ...
    ... produced 5 warnings and left the string unchanged (I presume the warnings were that $2 was undef)..

    Yes, because there is no capture group 2 ((?=.) is a non-capturing look-ahead) and the first capture group is being replaced with itself: $1.

Re: rotate a vector with a regex?
by AnomalousMonk (Abbot) on Nov 20, 2012 at 22:20 UTC
    ... move it pairwise along the string (bubble it).

    As I understand it, this won't work because substitution is not being done on the original string during the actual substitution process; rather, an intermediate string is being built up during this process, and the intermediate string is copied to the original string when the process is complete.

    That's why something like
        ($x = $y) =~ s{foo}{bar}xms;
    works as it does: instead of copying the intermediate back to the original string ($y), it's copied to another string ($x) leaving the original string untouched. (Or maybe $x is just used as the 'intermediate' in the first place. Whatever...)

      > rather, an intermediate string is being built up during this process, and the intermediate string is copied to the original string

      I think you're right

      DB<123> $x=join "",a..j => "abcdefghij" DB<124> $x =~ s/(.)(?=(.))/$2$1/g => 9 DB<125> $x => "bacbdcedfegfhgihjij"

      Cheers Rolf

Re: rotate a vector with a regex?
by remiah (Hermit) on Nov 21, 2012 at 04:23 UTC

    Hello, misterperl

    I wonder whether there is a way for setting pos in s///eg substitution?, I mean like this...

    s/(.)(.)/pos()=pos()-1; $2.$1/eg;
    
    With while loop, I will do like this.
    use strict; use warnings; my $str="6123457"; while ($str =~ /(.)/g){ last if pos($str) >= length($str); my $p=pos($str); #backup pos beause overwrite $str afterwards my $l=substr($str, pos($str) -1 ,1); my $r=substr($str, pos($str),1); substr($str, pos($str)-1, 2) = ($r >= $l) ? $l.$r : $r.$l ; #replace with lvalue of substr print "str=$str\n"; pos($str)=$p; } print "result=$str\n";
    regards.

      local $_ = '12345'; while( /(?=..)/g ) { my $pos = pos(); s/\G(.)(.)/$2$1/; pos() = $pos + length($2); } print $_, $/ __END__ 23451

      - tye        

        Hello tye. Thanks for reply

        zero width look ahead and \G .
        fine!

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (6)
As of 2014-09-17 04:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (57 votes), past polls