Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: strange usage of s///

by smls (Friar)
on Sep 03, 2013 at 17:21 UTC ( #1052146=note: print w/ replies, xml ) Need Help??


in reply to strange usage of s/// [solved: Perl 5.14 and 5.16 bug]

$_="abcdef"; s/@{[s".."."gr]}/$& /; print;

This variation of yours does in fact work (prints "abc def"), and so do the following ones (which are closer to the original solution by "tails"):

s/@{[s".."."gr]}\K/ /;
s/@{[s".."."gr]}\K/$"/;

Thus I conclude that the original "solution" is the result of a typo (separator '/' put in the wrong place), and cannot work.

As for how the corrected variations listed above work, lets break it down:

1)

s".."."gr;

If the input string in $_ has an even number of characters (which seems to be implicitly assumed here), then this expression will return a string consisting of only dots, of half the length of the input string. E.g. for the input string "abcdef" it returns "...".

2)

@{[ ]}

This is a common trick to execute a piece of code, and insert the code's return value directly into a string without introducing a temporary variable. It works because Perl interpolates anything that looks like an array variable inside a string.

3)
The above two expressions combined, will effectively produce the following substitution command in case of the input string "abcdef" (for the three different variations listed above):

s/.../$& /;
s/...\K/ /;
s/...\K/$"/;

All of them do the same thing: Insert a space after the third character of the original string, i.e. right in the middle.
(If you're still confused, see perlreref for an explanation of \K and $&.)

------
why $" is different from literal space character in this regex?

It isn't, unless you've manually changed that variable.
Maybe the author just liked a little obfuscation, or wanted to make it more "generic".


Comment on Re: strange usage of s///
Select or Download Code
Re^2: strange usage of s///
by davido (Archbishop) on Sep 03, 2013 at 17:30 UTC

    s/.././gr will convert each consecutive pair of any character (aside from newline) to single dots. If there's an extra (odd) character at the end, this won't be converted, but we don't worry about that because the input seems always to be strings of even numbered length.

    Also, don't forget the importance of /r here, as it causes the substitution to return its result without modifying the original string, which is important since we're still working with the original string in the outer layer.


    Dave

      #!perl -pl s/@{[s".."."gr]}\K$"//

      I understand the regex like this:

      s/....\K // (with the good number of '.')

      ...but in facts it works like this:

      s/....\K/ /

      I don't understand why. The usage of $" seems magic too...

      English is not my mother tongue.
      Les tongues de ma mère sont "made in France".
Re^2: strange usage of s///
by brx (Pilgrim) on Sep 03, 2013 at 20:27 UTC
    $_="abcdef"; s/@{[s".."."gr]}/$& /; print; [download]
    This variation of yours does in fact work (prints "abc def"), and so do the following ones (which are closer to the original solution by "tails")

    Not for me. It prints "...abcdef" (with perl v5.14.4).

    Thus I conclude that the original "solution" is the result of a typo (separator '/' put in the wrong place), and cannot work.

    No typo. Code is good. You can test it on: http://golf.shinh.org/p.rb?Bisection

    English is not my mother tongue.
    Les tongues de ma mère sont "made in France".

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2014-07-22 08:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (107 votes), past polls