How can I extract a file path from a Perl string?
I want to find the file name with fullpath from this string
"[exec] /snschome/sns/ccyp/mb_ccsns/bb/cbil5/v85_8/amdocs/iamcust/bil/cl/business/handlers/ClReportsHandler.java:233: cannot resolve symbol"
I want to extract
/snschome/sns/ccyp/mb_ccsns/bb/cbil5/v85_8/amdocs/iamcust/bil/cl/business/handlers/ClReportsHandler.java
and I am trying this in Perl
$_=$string_from_to_match my @开发者_Python百科extract_file=split(/.*(\/.*)\:.*/); print $extract_file[1],"\n";`
but I am getting this output:
/ClReportsHandler.java:233:
It is matching the last /
and the last :
. How can I change it to first /
and first :
?
This is a case where “tacking and stretching” is useful. You know that [exec]
followed by whitespace is on the left and colon followed by a line number is on the right. You want what's in between:
#! /usr/bin/perl
use warnings;
use strict;
$_ = "[exec] /snschome/sns/ccyp/mb_ccsns/bb/cbil5/v85_8/amdocs/iamcust/bil/cl/business/handlers/ClReportsHandler.java:233: cannot resolve symbol";
if (/\[exec\]\s*(.+?):\d+/) {
print $1, "\n";
}
If your file name doesn't contain spaces then you can create simple regexp to match all parts:
my ($file, $line, $msg) = ( $string_from_to_match =~ m{(\S+):([^:]+):([^:]+)} );
I've used:
\S+
to match 1 or more non-space symbols[^:]+
to match 1 or more not:
symbols
If you want spaces in path, then the best way is to remove starting [exec]
part and split by :
:
$string_from_to_match =~ s{^\[exec\]\s+}{};
my ($file, $line, $msg) = split(/:/, $string_from_to_match, 3);
You could try :
#!/usr/bin/perl
use strict;
use warnings;
use 5.10.1;
my $str = "[exec] /snschome/sns/ccyp/mb_ccsns/bb/cbil5/v85_8/amdocs/iamcust/bil/cl/business/handlers/ClReportsHandler.java:233: cannot resolve symbol";
$str =~ s!^[^/]*(/[^:]*):.*$!$1!;
say $str;
Ouput: /snschome/sns/ccyp/mb_ccsns/bb/cbil5/v85_8/amdocs/iamcust/bil/cl/business/handlers/ClReportsHandler.java
Why are you using split()
if you want to match?
if ($subject =~ m!(/[^:]+):!) {
$result = $1;
} else {
$result = "";
}
should do it.
Explanation:
!
: alternative regex delimiter (since I need the /
inside)
(
: start capturing group
/
: match a /
. This will always be the first /
of the string.
[^:]+
: match 1 or more characters except :
)
: end capturing group
:
: match a :
!
: regex delimiter
This is what I do:
if ($fullpath =~ /^(.+)\/([^\/]+)/)
{
my ($path, $file) = ($1, $2);
}
This works by matching anything except the last /. This may not work under Windows of course.
精彩评论