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

Here's a quick an' easy that I can't seem to find an answer to in my documentation searches. I ask that you regex wizards give me a helping hand (is that sacriligious to speak of wizardry in a holy establishment?).
$served = ($served =~ s/\/$//) if ($served =~ /^\/.+?\/$/);
Essentially, if a webpage I've served has been called with a trailing "/", I want to shear it off, $served being the actual webpage served out. So I'm saying:
if the served page has a trailing "/" { set served equal to a substition of served without the "/" }
This doesn't work, I assume because of the =~ in the substitution. What is the proper method?

Many thanks!

Replies are listed 'Best First'.
Re: Substitution Trickery
by dragonchild (Archbishop) on Mar 21, 2003 at 15:38 UTC
    Try this:
    $served =~ s/\/$// if ($served =~ /^\/.+?\/$/);
    You're setting $served equal to whether or not the substitution happened. Substitution is an in-place modifier.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      dragonchild has the right answer, but you could improve the readability of the statement various ways:
      $served =~ s!/$!! if $served =~ m!^/.+/$!; or $served =~ s!/$!! if $served =~ m!^/.!; or $served =~ s!(^/.+)/$!$1!;
Re: Substitution Trickery
by jmcnamara (Monsignor) on Mar 21, 2003 at 15:54 UTC

    Why not omit the test. If there isn't a trailing / then it won't be removed:
    # Remove trailing / if present $served =~ s/\/$//;

    --
    John.

      The test turns '/foo/' into '/foo', but avoids turning '/' into ''.


      We're not surrounded, we're in a target-rich environment!

        True but that isn't in the psuedo-code that lacertus presents.

        His test would also leave a trailing slash on 'foo/bar/'. Is that what is required? Perhaps lacertus will tell us.

        If it is required then the following would suffice:

        $served =~ s[/$][] if $served =~ m[^/.];

        --
        John.

Re: Substitution Trickery
by BrowserUk (Patriarch) on Mar 21, 2003 at 16:13 UTC

    If all you want to do is detect a trailing slash and remove it if present, you could do

    chop($served) if substr($served,-1) eq '/';

    Which I think is a bit clearer of your intent than the regex.


    Examine what is said, not who speaks.
    1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
    2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
    3) Any sufficiently advanced technology is indistinguishable from magic.
    Arthur C. Clarke.
Re: Substitution Trickery
by zby (Vicar) on Mar 21, 2003 at 15:58 UTC
    Do you really need to discern the case that the path in $served starts with a slash and when it does not? If not I would leave just: $served =~ s/\/$//.

    Update: Re: Re: Substitution Trickery gives the answer why the test is actually needed.

Re: Substitution Trickery
by diotalevi (Canon) on Mar 21, 2003 at 17:31 UTC

    My that's an ugly expression. Here's what you said, said differently. In fact, you really meant to use the substitution operator s/// (I used a different delimiter because I didn't want to have to escape the / in the regex).

    $served =~ s[/$][];
Re: Substitution Trickery
by lacertus (Monk) on Mar 21, 2003 at 22:11 UTC
    FROM POSTER

    *Thank* you gals/guys, this has helped tremendously. You people never cease to amaze me - I'd feel damn alone without all the help!
Re: Substitution Trickery
by awkmonk (Monk) on Mar 24, 2003 at 10:13 UTC

    More as a note of robustness, don't assume that the field is terminated by a slash.

    $served =~ s/^(.+) *$/$1/;

    just to get rid of any trailing spaces (they always seem to creep in just to annoy me).

    First rule of programming: Never code for an error you don't know how to handle.