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

Hi Monks,

I want to perform a function on every 'word' found in a string.

Basically pass each word through a function which randomly muddles up the middle letters of a word.

I have found 69688 that looks like it will do what I want.. however I dont get the same result as the example suggests:

use strict; my $test = "This is a sample string of text"; my $tost = $test; $test =~ s/(\w)(\w+)(\w)/$1&garble($2)$3/g; print "ONE: $test\n"; print 'TWO: '.&garble($tost); sub garble { # garbles the middle of a word leaving the first and last characters + alone eg hello -> hlelo my $ret = ''; my @txt = split(/\s/,$_[0]); foreach my $word (@txt){ if($word =~ m/(\w)(\w+)(\w)/){ my $start = $1; my $mid = reverse $2 ; my $end = $3; $ret .= $start.$mid.$end.' '; }else{ $ret .= $word.' '; } } return $ret; } # ONE: T?{&garble(hi)}s is a s?{&garble(ampl)}e s?{&garble(trin)}g of +t?{&garble(ex)}t # TWO: Tihs is a slpmae snirtg of txet
And yes, I am simply reversing the middle letters not randomly jumbling them.. again I am trying to find a nice clean way of doing this.

Any thoughts?

___ /\__\ "What is the world coming to?" \/__/ www.wolispace.com

Replies are listed 'Best First'.
Re: Executing a function within a regex
by ChemBoy (Priest) on May 10, 2004 at 02:31 UTC

    You need the /e (for evaluate) option on your substitution, so the function will be called instead of having its name interpolated:

    $test =~ s/(\w)(\w+)(\w)/$1 . &garble($2) . $3/eg;



    If God had meant us to fly, he would *never* have given us the railroads.
        --Michael Flanders

Re: Executing a function within a regex
by graff (Chancellor) on May 10, 2004 at 02:53 UTC
    ChemBoy didn't mention this detail, but if you compare his version of the regex against your original, you'll notice another difference, in addition to the use of "e". He used the concatenation operator "." to join $1, the output of the function and $3.

    In order for the "e" qualifier to do a proper job, the entire rhs (replacement portion) of the regex needs to be an executable perl statement -- not just a string with an embedded subroutine call.

Re: Executing a function within a regex
by zude (Scribe) on May 10, 2004 at 03:20 UTC
    To scramble every word in a string leaving first and last characters intact:
    $string = "Hello there this is a scrambled mess"; sub scramble($) { my @a; splice @a,rand (@a+1),0,$_ for split '',(shift); join '',@a; } ($scrambled = $string) =~ s/(?:(?<=\A\w)|(?<=\W\w))\w+?(?:(?=\w\Z)|(?= +\w\W))/scramble $&/eg; print "$scrambled\n";
    Hlelo trehe tihs is a smlbceard mess
Re: Executing a function within a regex
by BrowserUk (Patriarch) on May 10, 2004 at 03:11 UTC

    Sounds like your doing the same as in this Txet Maglning Glof, Ayobndy? thread.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
      Exactly!

      Thanks for the link, and thanks for all of the replys too!

      ___ /\__\ "What is the world coming to?" \/__/ www.wolispace.com