【问题标题】:RegEx in perl that Uses Groups to Extract Information From A Filepathperl 中的正则表达式,它使用组从文件路径中提取信息
【发布时间】:2016-02-01 01:40:19
【问题描述】:

所以我需要采用这种格式:2015-08-15_15-41-32_44100_logo.txt 并使用这两段代码从中提取日期、时间和频率。现在它的形式是<date>_<time>_<frequency>_logo.txt.Below 是我尝试使它成为一个正则表达式,但我知道我遗漏了一些东西。我如何在 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;
}

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    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+)/;
    

    其中qrquote-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$/;
    

    【讨论】:

    • 如果我想制作我的模式怎么办:qr/^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+) _44100_(\w+).(\w+)$/;哪里 44100 可以用任何频率代替?我也需要逃避吗?喜欢 44100 日元?如果您在上面查看我的编辑,打印 join(",",@listFiles);部分只打印一个数组地址,而不是其中包含的文件。 (如果它甚至包含任何东西)
    • @TerikBrunson 您不需要转义 44000,您只需要转义“特殊”字符,如点、* 等。您将获得一个数组引用,因为您的 grep_files 返回一个数组引用,而不是数组,因此@listFiles = grep_files... 将数组引用 grep_files 返回作为数组@listFiles 的第一个(也是唯一一个)元素。要么更改 grep_files 以返回一个数组,要么将其返回分配给一个标量,然后将其用作数组引用。
    • "你可以使用 \d+ 但它不一定匹配日期。"是的,但 \d\d​​ 也不是。
    【解决方案2】:

    你很接近,只是一些变化。这是脚本和测试运行:

    $ 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 strictuse warningsuse strict 会产生一些可疑的构造错误,use warnings 会警告脚本可能存在的一些问题。

    ls 显示当前目录中的示例文件,freq.pl 运行显示输出的脚本。

    【讨论】:

    • 好吧,我可能还不清楚其中的一部分。我不需要只提取频率。在每次调用时,我需要根据每个文件路径的频率对其进行分离并做一些不同的事情。出于某种原因,我不能只获得一个列表来返回与特定模式匹配的所有文件。是否可以让我的正则表达式包含特定频率?比如qr/^(\d+)-(\d+)-(\d+)_(\d+)-(\d+)-(\d+)_44100_(\w+).(\w+)$/
    • 您的“我需要能够获得频率”。当时还不清楚。 :-) 如果您想从 grep_files 中返回整个文件名,只需删除 s/$pat/$7/ foreach @files;,您将获得完整的文件名,然后您可以进一步操作。您还可以通过返回两个数组引用(或对二元素数组的引用数组)来返回文件名和频率。您可以通过将第 7 组更改为您想要的频率来匹配特定频率。有很多选择,只是取决于你想做什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    相关资源
    最近更新 更多