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

How can parse a string from the right instead of the left? What I'm trying to get is get the extension of a file contained in an URL, such as http://www.test.com/tmp/foo.bar. Here's my kludge: my ($ext) = $url =~ /\.(.+)$/; while ( $ext =~ /\./ ) { ($ext) = $ext =~ /\.(.+)$/; } In Korn Shell, I could use something like ${url%%/./}, but I'm not sure if that's right off the top of my head. Thanks

Edit: 2001-03-03 by neshura

  • Comment on parsing from the right instead of the left

Replies are listed 'Best First'.
RE: parsing from the right instead of the left
by chromatic (Archbishop) on Sep 23, 2000 at 03:20 UTC
    Writing a reverse regex seems like too much work for a lazy Perl hacker. I think you're on the right track, especially with the end-of-line anchor:

    (my $ext = $url) =~ m!\.([^/]+)$!;

    With greedy quantifiers like + and *, the regex engine parses from right to left anyway. So take advantage of that.

    Somehow, that construct isn't behaving for me after a long week, so here's another approach:

    #!/usr/bin/perl -w use strict; print "Url: "; chomp(my $url = <STDIN>); if ($url =~ m!\.([^/]+)$!) { print "Ext: $1\n"; } else { print "Not found.\n"; }
RE: parsing from the right instead of the left
by Adam (Vicar) on Sep 23, 2000 at 00:48 UTC
    reverse the string. There was also a post around here, sexeger, about this kind of thing.
RE: parsing from the right instead of the left
by japhy (Canon) on Sep 23, 2000 at 01:26 UTC
    I definitely suggest you check out Sex, Eger!, my paper (soon to be at perl.com!) on reversing regular expressions to match the last of something in a string.

    If you want to match forward, then you want to match the last sequence of non-. characters in a string. This can be matched by ($ext) = $str =~ /([^.]+)$/.

    If you want to reverse it, simply do $ext = scalar reverse( reverse($str) =~ /([^.]+)/).

    $_="goto+F.print+chop;\n=yhpaj";F1:eval