Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Can you assign to pos() in a s/foo/bar/g

by mwah (Hermit)
on Oct 25, 2007 at 12:48 UTC ( [id://647158]=note: print w/replies, xml ) Need Help??


in reply to Can you assign to pos() in a s/foo/bar/g

Whats wrong with:

my $str=q{DFR7234C__A_B_C_Bonzo_Dog_D_B}; $str =~ s/(?<=__)([A-Z]_)+//g;

I'd guess, pos() is localized within the code assertion. Pos() would be changeable within the while loop triggered by the regex (1st example). Maybe one of the gods may bring some light into this.

BTW, oha presented already a very nice solution here.

Regards

<mwa

Replies are listed 'Best First'.
Re^2: Can you assign to pos() in a s/foo/bar/g
by johngg (Canon) on Oct 25, 2007 at 19:06 UTC
    Whats wrong with: ... s/(?<=__)(A-Z_)+//g;

    Nothing (other than not needing the g modifier :-) but as I said, there are a lot of ways to tackle the problem and this particular question piqued my interest. I have tried accessing pos() inside the while loop but I get "Use of uninitialized value" warnings. Doing the same with a match rather than a substitution seems fine and I can even assign to pos() to affect where it matches.

    #!/usr/bin/perl -l # use strict; use warnings; $_ = q{DFR7234C__A_B_C_Bonzo_Dog_D_B}; print; while ( s{(?<=__)[A-Z]_}{} ) { print pos(); } print; print q{-} x 25; # --------------------- $_ = q{DFR7234C__A_B_C_Bonzo_Dog_D_B}; print; while ( m{_}g ) { print pos(); } print q{-} x 25; # --------------------- $_ = q{DFR7234C__A_B_C_Bonzo_Dog_D_B}; print; while ( m{_}g ) { print pos(); pos() = 23 if pos() >= 12 && pos() < 26; } print q{-} x 25; # ---------------------

    produces

    DFR7234C__A_B_C_Bonzo_Dog_D_B Use of uninitialized value in print at ./spw644148G line 11. Use of uninitialized value in print at ./spw644148G line 11. Use of uninitialized value in print at ./spw644148G line 11. DFR7234C__Bonzo_Dog_D_B ------------------------- DFR7234C__A_B_C_Bonzo_Dog_D_B 9 10 12 14 16 22 26 28 ------------------------- DFR7234C__A_B_C_Bonzo_Dog_D_B 9 10 12 26 28 -------------------------

    I agree with you, oha's solution is very nice indeed.

    Thank you for your reply,

    JohnGG

      I have a similar problem but could not get oha's solution to work...

      Problem: I have big files in which all appearances of following class-Attributes shall be shortened like so:
      Bla class="x1" class="x2" class="x3" Blabla
      ==> Bla class="x1 x2 x3" Blabla

      With the substitution

      s/\s*class=\"([^\"]*)\"\s*class=\"([^\"]*)\"\s*/ class="$1 $2" /sg;

      the result is: ==> Bla class="x1 x2" class="x3" Blabla

      A loop delivers of course the correct result:

      1 while s/class=\"([^\"]*)\"\s*class=\"([^\"]*)\"/class="$1 $2"/sg;

      But because the substitution would need several passes to get the result this is not my prefered way.
      I would like to have an option, that the substitution is starting again at the position right before the replacement and not after the replacement.
      I have tried several times to use \G in the substitution like this one:

      s/\G?class=\"([^\"]*)\"\s*class=\"([^\"]*)\"/class="$1 $2"/sg;

      or

      s/\G\s*class=\"([^\"]*)\"\s*class=\"([^\"]*)\"\s*/ class="$1 $2" / while /\s*class=\"([^\"]*)\"\s*class=\"([^\"]*)\"\s*/g;

      but to no success.
      Any Idea, to manage this substitution with one pass?

      PS: in oha's example there is a little error if the string starts with _ as f.e. $_ = q{_FR7234C__A_B_C_Bonzo_Dog_D_B};

        I'm not sure you need the complication of oha's method here as it depends on the fact that the left side of the alternation will still match once you have done the first substitution whereas in your problem it won't. Using just a capture group seems to work.

        $ perl -E ' > $_ = q{Bla class="x1" class="x2" class="x3" Blabla}; > say; > s{" class="([^"]+)}{ $1}g; > say;' Bla class="x1" class="x2" class="x3" Blabla Bla class="x1 x2 x3" Blabla

        Attacking the problem from (literally) a different direction would be another way of achieving the same result without a capture group.

        $ perl -E ' > $_ = q{Bla class="x1" class="x2" class="x3" Blabla}; > say; > $r = reverse $_; > $r =~ s{"=ssalc "}{ }g; > $_ = reverse $r; > say;' Bla class="x1" class="x2" class="x3" Blabla Bla class="x1 x2 x3" Blabla $

        I hope this is helpful.

        Cheers,

        JohnGG

        Update: I forgot to mention, double-quotes are not regex metacharacters so they don't need to be escaped.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-04-20 02:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found