Regex Perl使用正则表达式识别文件列表中的文件扩展名

Regex Perl使用正则表达式识别文件列表中的文件扩展名,regex,perl,Regex,Perl,我有一个很长的文件列表,我正试图根据它们的扩展名做出决定。这整件事必须是我的perl程序的一部分。以下是列表的一个示例: a.pj b.pj null c.xlsx gibberishWithNoExtension d.pj f.docx g.pj 1.17 and 1.15.1.1 决定规则如下: 1) If the extension is ".pj" do something. 2) If the extension is anything else do something else

我有一个很长的文件列表,我正试图根据它们的扩展名做出决定。这整件事必须是我的perl程序的一部分。以下是列表的一个示例:

a.pj
b.pj
null
c.xlsx
gibberishWithNoExtension
d.pj
f.docx 
g.pj 1.17 and 1.15.1.1
决定规则如下:

1) If the extension is ".pj" do something.
2) If the extension is anything else do something else
3) If there is something else after the extension (like version numbers) or there is no extension at all: ignore it
第一点应该相当简单。我猜是这样的:

my $string = a.pj;
if ($string =~ /.pj/) {
    say 'success!'
}
open (INP, "<path_of_file/file_list.txt") or die $!:
while( <INP> ) {
    chomp ( $_ );
    #~ whatever followed by dot '\.', then extension captured in a group '$1'
    #~ line must be evaluated as true only if its ended with a extension name
    #~ otherwise it'll be ignored (as you expect to do)
    if ( $_ =~ m/\.(.+)$/ ) {
        if( $1 eq "pj" ) { #~ 1) If the extension is ".pj" do something.
            #~ do something with pj extension
        } elsif ( $1 eq "xlsx" ) { # and other 'elses' rule 2)
            #~ do something with xlsx extension
        } elsif ( $1 eq "docx" ) {
            #~ do something with docx extension
        } elsif ( $1 eq "..." ) {
            #~ do something with ... extension
        } else {
            #~ do something with not expected extension
        }
    else { #~ rule 3) If there is something else after the extension
        #~ not a text formated as a file name followed by extension
    }
}
close (INP);

但我被其他案子缠住了。特别是在识别第3点时。你们中的一些人能帮我找到正确的正则表达式吗?

在2之前检查3似乎更容易:

#!/usr/bin/perl
use warnings;
use strict;

while (<DATA>) {
    chomp;
    if (/\.pj$/) {
        print "Doing something with $_\n";

    } elsif (/ / || ! /\./) {
        print "Ignoring $_\n";

    } else {
        print "Doing something else with $_\n";
    }
}

__DATA__
a.pj
b.pj
null
c.xlsx
gibberishWithNoExtension
d.pj
f.docx
g.pj 1.17 and 1.15.1.1

注意第一个正则表达式中的反斜杠。裸点匹配除换行符以外的任何内容,但您不希望匹配a.xpj。需要美元符号来防止匹配a.pjx。

在2之前检查3似乎更容易:

#!/usr/bin/perl
use warnings;
use strict;

while (<DATA>) {
    chomp;
    if (/\.pj$/) {
        print "Doing something with $_\n";

    } elsif (/ / || ! /\./) {
        print "Ignoring $_\n";

    } else {
        print "Doing something else with $_\n";
    }
}

__DATA__
a.pj
b.pj
null
c.xlsx
gibberishWithNoExtension
d.pj
f.docx
g.pj 1.17 and 1.15.1.1
注意第一个正则表达式中的反斜杠。裸点匹配除换行符以外的任何内容,但您不希望匹配a.xpj。需要美元符号来阻止匹配a.pjx。

的文件解析可以处理此问题。给它指定要使用的正则表达式,它会分解文件名:

use v5.10;
use File::Basename qw(fileparse);

while (<DATA>) {
    chomp;
    my( $name, $dir, $suffix ) = fileparse( $_, qr/\.[^.]+\z/ );
    say "$_ -> $suffix";
}
您提到要忽略某些作为扩展名的结尾。您可以定制正则表达式来实现这一点

一旦你有了分机,你就可以按你喜欢的任何方式进行分支

的fileparse可以处理这个问题。给它指定要使用的正则表达式,它会分解文件名:

use v5.10;
use File::Basename qw(fileparse);

while (<DATA>) {
    chomp;
    my( $name, $dir, $suffix ) = fileparse( $_, qr/\.[^.]+\z/ );
    say "$_ -> $suffix";
}
您提到要忽略某些作为扩展名的结尾。您可以定制正则表达式来实现这一点


一旦你有了分机,你就可以按你喜欢的任何方式进行分支

我知道你有一个很好的asnwer,但我想这样做:

my $string = a.pj;
if ($string =~ /.pj/) {
    say 'success!'
}
open (INP, "<path_of_file/file_list.txt") or die $!:
while( <INP> ) {
    chomp ( $_ );
    #~ whatever followed by dot '\.', then extension captured in a group '$1'
    #~ line must be evaluated as true only if its ended with a extension name
    #~ otherwise it'll be ignored (as you expect to do)
    if ( $_ =~ m/\.(.+)$/ ) {
        if( $1 eq "pj" ) { #~ 1) If the extension is ".pj" do something.
            #~ do something with pj extension
        } elsif ( $1 eq "xlsx" ) { # and other 'elses' rule 2)
            #~ do something with xlsx extension
        } elsif ( $1 eq "docx" ) {
            #~ do something with docx extension
        } elsif ( $1 eq "..." ) {
            #~ do something with ... extension
        } else {
            #~ do something with not expected extension
        }
    else { #~ rule 3) If there is something else after the extension
        #~ not a text formated as a file name followed by extension
    }
}
close (INP);

这样做的原因是,您只需要一次正则表达式求值,就可以为您希望处理的每个文件扩展名执行所需的操作。

我知道您有一个很好的asnwer,但我想这样做:

my $string = a.pj;
if ($string =~ /.pj/) {
    say 'success!'
}
open (INP, "<path_of_file/file_list.txt") or die $!:
while( <INP> ) {
    chomp ( $_ );
    #~ whatever followed by dot '\.', then extension captured in a group '$1'
    #~ line must be evaluated as true only if its ended with a extension name
    #~ otherwise it'll be ignored (as you expect to do)
    if ( $_ =~ m/\.(.+)$/ ) {
        if( $1 eq "pj" ) { #~ 1) If the extension is ".pj" do something.
            #~ do something with pj extension
        } elsif ( $1 eq "xlsx" ) { # and other 'elses' rule 2)
            #~ do something with xlsx extension
        } elsif ( $1 eq "docx" ) {
            #~ do something with docx extension
        } elsif ( $1 eq "..." ) {
            #~ do something with ... extension
        } else {
            #~ do something with not expected extension
        }
    else { #~ rule 3) If there is something else after the extension
        #~ not a text formated as a file name followed by extension
    }
}
close (INP);

这样做的原因是,您只需要一次正则表达式求值,就可以为希望处理的每个文件扩展名执行所需的操作。

我对您的解决方案非常满意,但我只是偶然发现了一个不起作用的案例。有一个文件不包含空格,但在扩展名后面包含一个版本号,例如:xyz.pj1.4.0。我如何捕获它?@UsefulUserName:您想如何对其进行分类?作为1、2或3?还是要为此类情况添加新类?案例3。我需要剔除/忽略任何格式不正确的内容。@UsefulUserName:如何判断abc.x1是文件名还是缺少空格的版本号的文件名?@UsefulUserName:关于}elsif/|[0-9]\.[0-9]+$/|!/\./{用于忽略?在一开始没有/|的情况下,它可能也可以工作。我对您的解决方案很满意,但我刚刚偶然发现了一个它不工作的情况。有一个文件不包含空格,但在扩展名后面包含一个版本号,例如:xyz.pj1.4.0。我如何捕获它?@UsefulUserName:您想如何将其分类为1、2或3?或者是否要为此类情况添加新类?案例3。我需要剔除/忽略任何格式不正确的内容。@UsefulUserName:如何区分abc.x1是文件名还是缺少空格的版本号的文件名?@UsefulUserName:关于}elsif/|[0-9]\.[0-9]+$/|!/\./{用于忽略?如果一开始没有/|它可能也可以工作。我曾经想过类似的事情。问题是我不知道,也永远不会知道列表中包含的所有扩展名。即使我知道,脚本也可能用于包含不同扩展名的不同文件的其他列表。谢谢你,它会ld是一个非常简洁的解决方案。我曾经想过类似的事情。问题是我不知道,也永远不会知道列表中包含的所有扩展名。即使我知道,脚本也可能用于包含不同扩展名的不同文件的其他列表。谢谢,这将是一个非常简洁的解决方案。