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

Alright I have a variable called.

$ext = "people.htm" $ext2 = "apple.cgi"
how can I pull of the extentions so $ext would now contain ".htm" and ".cgi", I know I have to use a regex for this but what?

Replies are listed 'Best First'.
Re: Finding a extention
by elusion (Curate) on Oct 05, 2002 at 16:02 UTC
    If you want to get the extension, you can do this:

    $ext =~ s/^.+(\.\w+)$/$1/;

    That substitutes the whole string with the last dot and what comes after. What behavior do you want with "foo.tar.gz"? The above regex will replace it with ".gz". If you want ".tar.gz", you should use

    $ext =~ s/^.+?(\.[\w\.]+)$/$1/;

    which searches for as little as possible in front, followed by a dot and one or more alphanumerics or dots. This can cause problems with directories that have dots in them though. If that becomes a problem, you will need to test for "/" in the regex. Hope this helps,

    elusion : http://matt.diephouse.com

Re: Finding a extention
by silent11 (Vicar) on Oct 05, 2002 at 16:18 UTC
    I use File::Basename It hasn't failed me yet.
    use File::Basename; my @exts = qw(.html .htm .shtml .pl .cgi .txt .etc); # list which ever + extensions you will be using. my $file1 = "people.htm"; # the file you want to parse ($name,$path,$suffix) = fileparse($file1,@exts); print "$suffix";
    returns: '.htm'

    -Silent11

      You can also use a regex so that you don't have to worry about listing all the possible extensions.

      foreach("fp.html", "fp.cgi", "fp.pl", "fp.foo", "fp.blah") { my ($base, $path, $type) = fileparse("/home/users/rich36/$_", qr{\ +..+}); print qq($base, $path, $type\n); } __RESULT__ fp, /home/users/rich36/, .html fp, /home/users/rich36/, .cgi fp, /home/users/rich36/, .pl fp, /home/users/rich36/, .foo fp, /home/users/rich36/, .blah
      «Rich36»
Re: Finding a extention
by robartes (Priest) on Oct 05, 2002 at 16:25 UTC
    This is Perl, so there's more than one way of doing this. One is indeed a regexp:
    $ext="i_am_the_walrus.txt"; $ext=~s/^[^.]*(\.[\w]+$)/$1/; print $ext;
    A second way is to use substr and index:
    use strict; my $filename="you_are_the_whale.doc"; my $separator="."; unless (($where=index($filename,$seperator) == -1) { my $ext=substr($filename,$where); print $ext; } else { print "No extensions in the zoo.\n"; }
    The third, and probably nicest way, is to use File::Basename:
    use strict; use File::Basename; my $filename="we_are_not_all_mammals.zoo"; my ($base, $directory, $ext)=fileparse($filename, '\.[\w]+$'); print $ext;
    Beware that the above assumes you're dealing with simple .xyz extensions. For more complicated stuff, see the regexp in elusion's reply above.

    CU
    Robartes-

    Update: Fixed regexp so it actually works :) (thx elusion). Adapted second recipe to include dot.

Re: Finding a extention
by fruiture (Curate) on Oct 05, 2002 at 16:35 UTC

    The question is, as elusion mentioned: Dou you want to split in the first dot or on the last. Consider using substr() and index() or rindex(), which is much faster than a regexp:

    for(qw/ people.html apple.cgi foo.tar.gz .hidden /){ if( (my $fd = index($_,'.')) > 0 ){ printf "%s =FD=> %s\n", $_ => substr($_,$fd) } if( (my $ld = rindex($_,'.')) > 0 ){ printd "%s =LD=> %s\n", $_ => substr($_,$ld) } }
    --
    http://fruiture.de