【问题标题】:perl foreach loop skip iteration for specific file under specific folderperl foreach 循环跳过特定文件夹下特定文件的迭代
【发布时间】:2015-04-30 14:40:26
【问题描述】:

我有 perl 脚本可以从我的处理中排除一些路径。 现在我想在排除路径中添加一个新文件夹(/foo/),除了文件名Hello

我知道我们可以使用关键字next 来跳过循环,但是我怎样才能只为特定文件夹下的一个文件实现它呢?

文件夹/foo/ 可以在任何目录中,例如abc/foo/def/hij/klm/foo/

use strict;
use warnings;

my @excludepaths = (
  "abc/def/",
  "hij/klm/",   
);


foreach (@excludepaths)
{
  if (SOME_TEST_CONDITION) # exclude filename "Hello" under "Foo" folder
   {
      # move on to the next loop element
      next;
   }

 # more code here ...
}

【问题讨论】:

    标签: perl foreach next


    【解决方案1】:

    诀窍是 - 创建一个正则表达式,并使用 | 创建一个或条件。

    所以使用你的:

    my @excludepaths = (
      "abc/def/",
      "hij/klm/",   
    );
    

    像这样把它变成一个正则表达式:

    my $regex = join ( "|", map { quotemeta } @excludepaths ); 
       $regex = qr/($regex)/; 
    

    那你应该可以了

    next if m/$regex/;
    

    例如:

    my @excludepaths = (
      "abc/def/",
      "hij/klm/",   
    );
    
    my $regex = join ( "|", @excludepaths ); 
       $regex = qr/($regex)/; 
    
    for ( "abc/def/ghk", "abf/de/cg", "abf/hij/klm/ghf", "fish/bat/mix" ) {
       next if m/$regex/;
       print;
       print "\n";
    }
    

    如果您这样做,您可以将您喜欢的任何模式添加到您的“排除”中,只需将其添加到列表中即可。

    所以你可以添加/foo/.*/Hello$,它会跳过匹配:

    /some/path/to/foo/and/more/Hello
    

    因为正则表达式路径是子字符串匹配。

    编辑:根据您的 cmets:

    my @excludepaths = ( "abc/def/", "hij/klm/", "/foo/", );
    
    my $regex = join( "|", @excludepaths );
    $regex = qr/($regex)/;
    
    my $include_regex = qr,/foo/.*\bHELLO$,;
    
    for (
        "abc/def/ghk",              "abf/de/cg",
        "abf/hij/klm/ghf",          "fish/bat/mix",
        "/path/with/foo/not/HELLO", "/path/with/foo/",
        "/path/with/foo/HELLO"
        )
    {
        next if ( m/$regex/ and not m/$include_regex/ );
        print;
        print "\n";
    }
    

    我们明确排除包含/foo/ 的任何内容,但使用$include_regex 覆盖,这样/path/with/foo/not/HELLO 仍会通过文件管理器。

    【讨论】:

    • 您的代码不包括@excludepaths 中列出的整个目录。但我想排除所有那些,如果有一个目录/foo/,那么忽略其中的文件名HELLO并排除其余所有
    • 啊,好的。误解了您要查找的内容。您排除的例外情况,对吗?所以你的测试条件实际上是unless m,/foo/.*/Hello,?
    • @Sorbique :如果路径是 /some/path/to/foo/Hello$include_regex 条件是否仍然有效?如果文件 Hello 就在文件夹 foo 下?
    • 很好看,是的 - 这会坏掉,因为它必须是 foo//HELLO。修改后的代码 - 现在应该可以工作了。
    • 应该使用quotemeta perldoc.perl.org/functions/quotemeta.html> 以便转义字符串中的特殊字符:my $regex = join ( "|", map { quaotemeta } @excludepaths );
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多