我有这个目录路径:
\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1
如何testQEM.txt
从上面的字符串中获取文件名?
我用这个:
$file =~ /(.+\\)(.+\..+)(\\.+)/;
但是得到这个结果:
file = testQEM.txt\main\ABC_QEM
谢谢,
吉荣
我不确定我是否理解,因为路径不能在它们中间有一个文件节点!是否以某种方式连接了多个路径?
无论如何,我建议您通过路径寻找第一个验证为真实文件的节点,使用-f
这是一个例子
use strict;
use warnings;
my $path = '\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1';
my @path = split /\\/, $path;
my $file = shift @path;
$file .= '\\'.shift @path until -f $file or @path == 0;
print "$file\n";
这有点困难,因为目录名称可以包含句点。对于 *nix 系统尤其如此,但在 Windows 下也有效。
因此,每个可能的子路径都必须针对文件性进行迭代测试。
我可能会尝试这样的事情:
my $file;
my $weirdPath = q(/main/ABC_PRD/ABC_QEM/1/testQEM.txt/main/ABC_QEM/1);
my @parts = split m{/} $weirdPath;
for my $i (0 .. $#parts) {
my $path = join "/", @parts[0 .. $i];
if (-f $path) { # optionally "not -d $path"
$file = $parts[$i];
last;
}
}
print "file=$file\n"; # "file=testQEM.txt\n"
我split
在所有斜杠上都是奇怪的路径(如果互操作性对您来说不是问题,请更改为反斜杠)。然后我将第一个$i+1
元素连接在一起并测试路径是否为普通文件。如果是这样,我存储路径的最后一部分并退出循环。
如果您可以保证该文件是路径中唯一包含句点的部分,那么最好使用其他解决方案之一。
/[^\\]+\.[^\\]+/
.
捕获由两个反斜杠之间的分隔的任何内容。这就是你要找的东西吗?
我建议你可以理解正则表达式回溯的原理,比如 * 和 + 是如何工作的。您只需对您的正则表达式进行一点更改:
/(.+\\)(.+\..+?)(\\.+)/
>echo "\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1"|perl -pi -e "s/.*([\\][a-zA-Z]*\.txt).*/\1/"
\testQEM.txt
my $file = '\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1';
my ($result) = $file =~ /\\([^\\]+\.[^\\]+)\\/;
$result 周围的括号强制右侧表达式上的列表上下文,这反过来又返回括号中的匹配项。
使用正则表达式模式/(?=[^\\]+\.)([^\\]+)/
my $path = '\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1';
print $1 if $path =~ /(?=[^\\]+\.)([^\\]+)/;
在此处测试此代码。