Re: Quick Regex Needed
by Your Mother (Archbishop) on Oct 21, 2008 at 19:01 UTC
|
I don't know how fast this is compared to possible regular expressions but this is how I'd start -- given the limited problem description -- and benchmark against other options if this (or a variant of it) isn't fast enough.
my $input = '\one\two\three\four';
my $last = ( split /\\/, $input )[-1];
print $last, "\n";
| [reply] [d/l] |
Re: Quick Regex Needed
by ikegami (Patriarch) on Oct 21, 2008 at 19:28 UTC
|
use File::Basename qw( basename );
my $fn = basename($path);
File::Basename is a core module.
| [reply] [d/l] |
|
|
Right, but it's important to know what sort of system you happen to be using, so that you invoke the fileparse_set_fstype() function when necessary:
$ uname -s
Darwin
$ echo '\one\two\three\four'
\one\two\three\four
$ echo '\one\two\three\four' |
perl -MFile::Basename -lne 'print basename($_)'
\one\two\three\four
$ echo '\one\two\three\four' |
perl -MFile::Basename -lne 'BEGIN{fileparse_set_fstype("DOS")} prin
+t basename($_)'
four
The above would work out the same way if the result of "uname -s" had been linux or unix.
| [reply] [d/l] [select] |
|
|
Only if you assume he wasn't dealing with a path in the first place.
I assumed the OP was dealing with paths. If he's not, I believe he's better off not using File::Basename at all rather than your workaround.
| [reply] |
|
|
#!/usr/bin/perl --
use strict;
use warnings;
use Path::Class;
print file(qw' \one\two\three\four ')->basename;
print "\n";
__END__
four
| [reply] [d/l] |
Re: Quick Regex Needed
by gwadej (Chaplain) on Oct 21, 2008 at 19:16 UTC
|
I would probably use: m/([^\\]+)$/
Since this is a pretty easy regex problem, you obviously need to sit down with a good regex doc and go over the basics.
Some useful points:
- You are matching at the end of the string so $ is very useful.
- You are trying to extract something that does not match a particular character, use a negated character class.
- You are trying to extract data, use capturing parentheses.
Your Mother also gave a good solution, following the advice from Mastering Regular Expressions.
"If you know what you want to keep use the match operator, if you know what you want to discard, use split" (paraphrased, badly).
| [reply] [d/l] [select] |
Re: Quick Regex Needed
by dorko (Prior) on Oct 21, 2008 at 19:01 UTC
|
This seems to work:
.+\\(.+)
But it makes some assumptions about your data. Namely there is at least one blackslash and there is at least one character before and after the backslash.
Cheers,
Brent
| [reply] [d/l] |
Re: Quick Regex Needed
by gone2015 (Deacon) on Oct 21, 2008 at 23:30 UTC
|
my $foo = "\\one\\two\\three\\four" ;
my $bar = substr($foo, rindex($foo, "\\") +1) ;
or did it have to be a regex ?
| [reply] [d/l] [select] |
Re: Quick Regex Needed
by DutchCoder (Scribe) on Oct 21, 2008 at 18:53 UTC
|
Why wouldn't a regular expression be fast enough? How quick must it be?
With a little light reading and trial-and-error you might come up with something like this:
my $quick = '\one\two\three\four';
my $endpart = ($quick =~ m/([^\\]*)$/ ) ? $1 : '';
print qq|The end part is $endpart\n|;
| [reply] [d/l] |
|
|
| [reply] |
|
|
Yeah, I know, but I couldn't resist putting in a silly remark while working on something helpful (the question just screamed for it). But all is well now :D
| [reply] |
Re: Quick Regex Needed
by Anonymous Monk on Oct 22, 2008 at 01:32 UTC
|
#!/usr/bin/perl --
use strict;
use warnings;
my $str = qw~ \one\two\three\four ~;
print "$str\n";
print "$1\n" if $str =~ m~[\\/]([^\\/]+)$~;
print $str =~ m~[\\/]([^\\/]+)$~;
print "\n";
print scalar reverse($1),"\n" if reverse($str) =~ m~^([^\\/]+)~;
print scalar reverse( reverse($str) =~ m~^([^\\/]+)~); # sexeger
print "\n";
use YAPE::Regex::Explain;
print YAPE::Regex::Explain->new(qr~[\\/]([^\\/]+)$~)->explain;
__END__
\one\two\three\four
four
four
four
four
The regular expression:
(?-imsx:[\\/]([^\\/]+)$)
matches as follows:
NODE EXPLANATION
----------------------------------------------------------------------
(?-imsx: group, but do not capture (case-sensitive)
(with ^ and $ matching normally) (with . not
matching \n) (matching whitespace and #
normally):
----------------------------------------------------------------------
[\\/] any character of: '\\', '/'
----------------------------------------------------------------------
( group and capture to \1:
----------------------------------------------------------------------
[^\\/]+ any character except: '\\', '/' (1 or
more times (matching the most amount
possible))
----------------------------------------------------------------------
) end of \1
----------------------------------------------------------------------
$ before an optional \n, and the end of the
string
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
sexeger, YAPE::Regex::Explain | [reply] [d/l] |