Re: Grabbing file prefixes with Reg Exp
by MrNobo1024 (Hermit) on May 13, 2001 at 20:19 UTC
|
grep returns the whole filenames, not just a parenthesized group. I think what you want is
my @audiofiles = map { /([^\.]+)\.ram/i ? $1 : () } readdir DH;
| [reply] [d/l] |
|
| [reply] |
Re: Grabbing file prefixes with Reg Exp
by tomhukins (Curate) on May 13, 2001 at 20:25 UTC
|
The parentheses grab into $1, but grep
works with $_.
Also, there is a problem with your regular expression. It
will match any file containing .ram, not just files
ending in this extension.
Be aware that as you are
matching case insensitively, your regexp will also match
files containing the string .RAM or .rAm.
I'm assuming this is okay. Try:
my @audiofiles = grep { s/\.ram$//i } readdir DH;
| [reply] [d/l] [select] |
|
| [reply] |
Re: Grabbing file prefixes with Reg Exp
by japhy (Canon) on May 13, 2001 at 23:51 UTC
|
Allow me to point out some places of improvement:
- to see if a string ends in something, you must anchor it with \z, \Z, or $
- match what you need; this is wasteful: /.*\.foo$/
- using /i is sometimes wasteful, especially for a few characters
That said, I offer:
my @files = map s/\.[Rr][Aa][Mm]$// ? $_ : (), readdir DH;
Maybe you think those character classes look ugly, and maybe the difference is minimal, but in a case like this, I think it's a wise investment. Also, you may wish to use a different ending anchor in place of $.
japhy --
Perl and Regex Hacker | [reply] [d/l] |
|
using /i is sometimes wasteful, especially for a few characters
<counteropinion>
Unless the regexp is going to be in a performance-sensitive area of code, the performance gained by using character classes instead of /i is going to be outweighed by the readability hit.
To my eye, it's easier (albeit only slightly so) to grasp the intent of
my @files = map s/\.ram$//i ? $_ : (), readdir DH;
than it is to grasp
my @files = map s/\.[Rr][Aa][Mm]$// ? $_ : (), readdir DH;
When hardware performance isn't an issue, optimize for wetware (readability).
| [reply] [d/l] [select] |
|
Didn't you mean to make this a grep? :)
my @files = grep s/\.ram$//i , readdir DH;
Also, I agree with dws regarding the readability of the character classes, and believe you're altogether mistaken regarding the performance issue:
use strict;
use Benchmark qw(cmpthese);
my $strorig = 'yabadabadooo this bud is a buda fora youa';
cmpthese (-3, {
mod => sub { my $str = $strorig; $str =~ m/.*BUD.*/i },
class => sub { my $str = $strorig; $str =~ m/.*[Bb][Uu][Dd].*/ },
});
## Results (under ActiveState 5.6) ##
Rate class mod
class 347719/s -- -15%
mod 408606/s 18% --
MeowChow
s aamecha.s a..a\u$&owag.print | [reply] [d/l] [select] |
|
Yes, it was meant to be a grep() -- I took the map() and modified it, and forgot to change it.
And I guess I'm mistaken about char classes. I was using information from MRE, I think, which is now oldish, so Perl has probably made some changes.
japhy --
Perl and Regex Hacker
| [reply] |
Re: Grabbing file prefixes with Reg Exp
by Kanji (Parson) on May 13, 2001 at 20:29 UTC
|
my @auditofiles = grep { s/\A([^.]+)\.ram\z/$1/i }
readdir DH;
--k.
| [reply] [d/l] [select] |
|
Any reason for using the \A ... \z assertions instead of the commonplace ^ ... $ metachars? I believe that's the first I've seen those two used. More generally, is there a difference, outside of multiline-matching mode?
MeowChow
s aamecha.s a..a\u$&owag.print | [reply] |
|
\z only matches at the end of the string, but $ can match before a newline at the end. Unless you're using multiline mode, \A and ^ are the same.
| [reply] |