Reputation: 13676
I am new to Perl, so this is basic question. I have a string as shown below. I am interested in taking date out of it, so thinking of splitting it using slash
my $path = "/bla/bla/bla/20160306";
my $date = (split(/\//,$path))[3];#ideally 3 is date position in array after split
print $date;
However, I don't see the expected output, but instead I see 5 getting printed.
Upvotes: 3
Views: 8898
Reputation: 66881
Since the path starts with the pattern /
itself, split returns a list with an empty string first (to the left of the first /
); one element more. Thus the posted code miscounts by one and returns the one before last element (subdirectory) in the path, not the date.
If date is always the last thing in the string you can pick the last element
my $date = (split '/', $path)[-1];
where i've used ''
for delimiters so to not have to escape /
. (This, however, may confuse since the separator pattern is a regex and //
convey that, while ''
may appear to merely quote a string.)
This can also be done with regex
my @parts = $path =~ m{([^/]+)}g;
With this there can be no inital empty string. Or, the last part can be picked out of the full list as above, with ($path =~ m{...}g)[-1]
, but if you indeed only need the last bit then extract it directly
my ($last_part) = $path =~ m{.*/(.*)};
Here the "greedy" .*
matches everything in the string up to the last instance of the next subpattern (/
here), thus getting us to the last part of the path, which is then captured. The regex match operator returns its matches only when it is in the list context so parens on the left are needed.
What brings us to the fact that you are parsing a path, and there are libraries dedicated to that.
For splitting a path into its components one tool is splitdir
from File::Spec
use File::Spec;
my @parts = File::Spec->splitdir($path);
If the path starts with a /
we'll again get an empty string for the first element (by design, see docs). That can then be removed, if there
shift @parts if $parts[0] eq '';
Again, the last element alone can be had like in the other examples.
Upvotes: 6
Reputation: 5927
Try this
Use look ahead for to do it. It capture the /
by splitting. Then substitute the data using /
for remove the slash.
my $path = "/a/b/c/20160306";
my $date = (split(/(?=\/)/,$path))[3];
$date=~s/^\///;
print $date;
Or else use pattern matching with grouping for to do it.
my $path = "/a/b/c/20160306";
my @data = $path =~m/\/(\w+)/g;
print $data[3];
Upvotes: 0
Reputation: 43169
Simply bind it to the end:
(\d+)$
# look for digits at the end of the string
See a demo on regex101.com. The capturing group is only for clarification though not really needed in this case.
In Perl
this would be (I am a PHP/Python guy, so bear with me when it is ugly)
my $path = "/bla/bla/bla/20160306";
$path =~ /(\d+)$/;
print $1;
See a demo on ideone.com.
Upvotes: 1