所以我需要采用这种格式的东西:2015-08-15_15-41-32_44100_logo.txt
并使用这两段代码从中提取日期,时间和频率。现在它的形式是<date>_<time>_<frequency>_logo.txt.
以下是我试图使它成为一个正则表达式,但我知道我错过了一些东西。如何在perl中使用组来执行此操作?
下面的代码在目录中搜索模式后面的每个文件路径,并在列表中返回这些文件。我需要帮助的是正则表达式本身。我需要能够获得频率。
$pattern =qr/^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)_44100_(\w+).(\w+)$/;
@listFiles = grep_files($bee_music_dir,$pattern);
print join(",",@listFiles);
sub grep_files {
my ($dir, $pat) = @_;
opendir(my $dir_handle, $dir) or die $!;
my @files = grep { $_ =~ /$pat/ } readdir($dir_handle);
closedir($dir_handle);
return \@files;
}
答案 0 :(得分:0)
你很亲密,只是做了一些改变。这是脚本和测试运行:
$ cat freq.pl
#!/usr/bin/perl --
use strict;
use warnings;
my $pattern = qr/^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)_(\d+)_(\w+).(\w+)$/;
sub grep_files {
my ($dir, $pat) = @_;
opendir(my $dir_handle, $dir) or die $!;
my @files = grep { $_ =~ /$pat/ } readdir($dir_handle);
s/$pat/$7/ foreach @files;
closedir($dir_handle);
\@files;
}
print join("\n", @{grep_files '.', $pattern}), "\n";
$ ls
2015-08-15_15-41-32_44100_logo.txt freq.pl
2015-08-25_25-41-32_48000_logo.txt
$ ./freq.pl
44100
48000
freq.pl从当前目录中的文件名中提取频率。它基于你的,有一些关键的区别:
s/$pat/$7/ foreach @files;
遍历与模式匹配的所有文件,并用第7组替换所有文件,即频率。您还可以使用map
代替grep
一步选择文件并提取频率。use strict
和use warnings
。 use strict
会产生一些可疑的构造错误,use warnings
会警告脚本可能出现的一些问题。 ls
显示当前目录中的示例文件,freq.pl
运行显示输出的脚本。
答案 1 :(得分:0)
perl中的正则表达式组使用如下:
my ($a, $b, $c) = $somestring=~ /(\d+)-(\d+)-(\d+)/;
此处,列表($a, $b, $c)
中的每个变量都会分配匹配组的值,这些组也可用作$1
,$2
和$3
。所以上面这行等同于:
$somestring =~ /(\d+)-(\d+)-(\d+)/;
my ($a, $b, $c) = ($1, $2, $3);
(你甚至可以做my $a = $1; my $b = $2; my $c = $3
)。
如果你想声明一个$pattern
变量,你应该这样做:
my $pattern = qr/(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)_(\d+)_(\w+).(\w+)/;
其中qr
是quote-regexp
运算符,预编译正则表达式以进行优化。您不应在此处使用=~
运算符,因为它会将正则表达式应用于$pattern
,而不是将$pattern
定义为正则表达式。
以这种方式定义图案只允许
$stringtomatch =~ $pattern;
(但=~ /$pattern/
也可以。)
用于匹配格式为2015-08-15_15-41-32_44100_logo.txt
或<date>_<time>_<frequency>_logo.txt
的文件的正则表达式如下所示:
/^(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d)-(\d+)_logo\.txt$/
您可以使用\d+
,但不一定与日期匹配。此外,正则表达式中的.
表示“任何字符”,因此如果您的意思是.
,则应该将其转义:\.
。
以下是您的子部分的更详细版本,说明了对群组的访问:
my @files = ();
while ( my $file = readdir($dir_handle) ) {
if ( my ($year,$month,$day,$hour,$minute,$second,$freq) = $file =~ $pattern ) {
# do something with $freq
push @files, $file;
}
}
如果你所追求的只是一个频率列表,那么仅对所需字段进行“分组”就足够了:
my $pattern = qr/^\d+-\d+-\d+_\d+-\d+-\d+_(\d+)_logo\.txt$/;