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

Im new to perl, and I searched the database, but couldn't find a way to replace the last letter of a certain type in a string with another string.... for example

$tofind = "s"; $replacement = "X"; $variable = "snaskes";
after the code did its thing, I would want

$variable = "snaskeX";

I assume this is easier then I think, and I assume it uses s/// or tr/// but Im not sure how.
thanks

Janitored by Arunbear - added code tags

Replies are listed 'Best First'.
Re: Replace the last letter
by Limbic~Region (Chancellor) on Oct 07, 2004 at 17:10 UTC
    Anonymous Monk,
    The following code should do what you want provided that $find string is present in $string.
    substr( $string, rindex( $string, $find ), 1, $replace );
    You can use perldoc -f <function> to find out how substr and rindex work. You can also experiment to see what happens if $find isn't in the string.

    Cheers - L~R

Re: Replace the last letter
by mifflin (Curate) on Oct 07, 2004 at 17:08 UTC
    This will replace the last character...
    $find = 's'; $replace = 'X'; $string = 'Snakes'; $string =~ s/$find$/$replace/; print $string, "\n";

      Personally I'd go down the regex route too for preference. If the find/replace chars that you're using are always the same then you can improve the effeciency with just:

      $string = 'Snakes'; $string =~ s/s$/X/;

      If you want to take the substr() route then try:

      substr($string,-1,1,'X');

      That will replace the last character whatever it is with the X. For more details I'd also point you towards the perldocs - if you don't have access to the perldoc function then look it up on http://www.perldoc.com.

      --- Jay

      All code is untested unless otherwise stated.

        If you always want the last letter, you could match:

        $string =~ s/.$/X/; ## or $letter = 'X'; $string =~ s/.$/$letter/;
        As opposed to the substr use.

        radiantmatrix
        require General::Disclaimer;
      What about replacing the last occurance of 's' in the word 'systematic'? I think the OP should have stated the question more clearly, that he wants the last occurance of a certain letter, not the last letter of the string.

Re: Replace the last letter
by !1 (Hermit) on Oct 07, 2004 at 17:10 UTC
    substr($variable, rindex($variable,$tofind), length($tofind), $replace +ment) if rindex($variable,$tofind) > -1;
Re: Replace the last letter
by shemp (Deacon) on Oct 07, 2004 at 17:32 UTC
    I think that a lot of these responses misinterpreted the requirements. The OP is not saying replace the last letter, but instead the last letter of a certain type, i.e. the last 's' or the last 'p' for instance.
      It seems to me that this was recently posted about on this site.
      #!/usr/bin/perl use strict; my $find = "r"; my $replace = "X"; my $input = "superfrink"; my $tmp = reverse $input; $tmp =~ s/$find/$replace/; my $output = reverse $tmp; print "input: $input \n"; print "output: $output \n";

      Update: Here is the sample output.
      frink@scanbox:~ $ ./397370.pl input: superfrink output: superfXink frink@scanbox:~ $
Re: Replace the last letter
by shemp (Deacon) on Oct 07, 2004 at 17:09 UTC
    #!/usr/bin/perl use strict; use warnings; my $tofind="s"; my $replacement="X"; my $variable="snaskes"; print "Before: $variable\n"; $variable =~ s/$tofind[^$tofind]*$/$replacement/; # OR # $variable =~ s/$tofind(?![$tofind])$/$replacement/; print "After: $variable\n";

      The main version does the right thing, but the alternative doesn't - negative lookahead will look for something immediately following, so:

      $variable =~ s/$tofind(?![$tofind])$/$replacement/;
      means "find the letter, not followed by the letter again, but followed by the end anchor". I think you want instead:
      $variable =~ s/$tofind(?!.*$tofind)/$replacement/;
      ie "find the letter, not followed by (zero or more characters and) the letter again".

      Also, the [$tofind] character class is the same as $tofind itself when it refers to a single letter, but doesn't do the right thing if $tofind is something more complex.

      Hugo

Re: Replace the last letter
by Golo (Friar) on Oct 07, 2004 at 17:13 UTC
    not sure if that is really elegant or effective (compared to a regex), but it was the first thing that came to my mind:
    my $tofind="s"; my $replacement="X"; my $variable="snaskes"; my $tmp = chop $variable; $variable .= $tmp eq $tofind ? $replacement : $tmp; print $variable;
Re: Replace the last letter
by CountZero (Bishop) on Oct 07, 2004 at 19:54 UTC
    What about

    s/(.*)$tofind(.*)/$1$replacement$2/

    It relies upon the greediness of the regex engine to match as much as possible as soon as possible.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: Replace the last letter
by TrekNoid (Pilgrim) on Oct 07, 2004 at 18:44 UTC
    In the 'yet another way to do it' category:
    my $tofind="s"; my $replacement="X"; my $variable="snaskes"; substr($variable, -1, 1) = $replacement if (substr($variable, -1, 1) e +q $tofind); print "$variable\n";
    Trek

    Update: Thanks to the CB folks for pointing out the mistake! Edited.

      I noted this got downvoted, which is fine... I'm not seeking argument to that

      I would appreciate knowing, however, why. I'm always wanting to improve my skills, and if I've done something unknowingly wrong here, please let me know so I can correct it in the future

      I think I've shown in the past that I'm willing to learn from my own mistakes when shown why

      Maybe others here take offense to being corrected, but I appreciate it.

      Trek

Re: Replace the last letter
by Fletch (Bishop) on Oct 07, 2004 at 17:08 UTC
    perldoc -f substr
Re: Replace the last letter
by Anonymous Monk on Oct 07, 2004 at 17:13 UTC
    YAY, thank you all. very fast :)
Re: Replace the last letter
by Roger (Parson) on Oct 08, 2004 at 02:06 UTC
    This is a no brainer. There are many solutions.

    # reverse the string and replace first occurance
    # since no monk has suggested this simple solution yet.
    $variable = reverse $string; $variable =~ s/$tofind/$replace/; $variable = reverse $string;