【问题标题】:Match multiple elements of array Perl匹配数组 Perl 的多个元素
【发布时间】:2013-06-11 10:38:16
【问题描述】:

我正在使用File::Find 搜索目录。然后我想使用@ARGV 来匹配用户输入的术语。我只希望使用第一个到倒数第二个元素进行匹配(最后一个是输出名称)。我虽然我的代码可以工作,但它不是,有什么想法吗?

if ($File::Find::name =~ m/$_/ for @ARGV[0..-2]){
    #manipulate filenames
}

谢谢。

【问题讨论】:

  • 请定义:"match terms"。你真的是说"compare file names"吗?
  • 我的意思是对@ARGV 中保存的元素使用匹配,即如果我运行perl script.pl match1 match2 output,我想将术语“match1”和“match2”与路径匹配。
  • 这种解释即使在 6 小时前出现也无济于事。如有疑问,请举个例子。

标签: arrays perl match elements


【解决方案1】:

你为什么要在这里使用$File::Find::name?那是相对路径,而不仅仅是文件名。我假设您正在尝试在此处匹配文件名。你可以这样做:

my $output = pop @ARGV;             # now you can use @ARGV freely
my $regex  = join "|",              # join by alternations
                 map quotemeta,     # disable meta characters
                 @ARGV;             # list of file names
find(sub { 
        /$regex/i or return;        # quick check
        # manipulate files...
     }, $dir);

您可以进行一些调整,例如是否禁用元字符、是否使用不区分大小写 /.../i

文档:popjoinquotemeta

【讨论】:

  • 您认为我想匹配文件名的假设是不正确的,我在不同的目录中有多个文件,名称相同(坏主意,我知道!)并且我试图根据以下文件找到其中一些文件目录和文件名。不过感谢您的回复,这本身就很有趣。
  • @bruce01 是的,“匹配条款”并不十分清楚。但是我认为您没有看到我的回答中的重点:您编译了一个正则表达式来比较路径,而不是使用循环。所以,将/$regex/ 切换为$File::Find::name =~ /$regex/
  • 我认为很清楚:约定$str =~ m/sthng/ 是匹配语句,而我要匹配的是术语。这里正确的命名是什么?我确实看到了您在做什么,我只是使用了上面的另一种方法,因为我发现在返回脚本时对自己来说更清楚了。再次感谢您的时间和帮助,非常感谢。
【解决方案2】:

EXPR for LIST 是一个语句,而不是一个表达式。 if (COND) {BLOCK} 期望 COND 是一个表达式。

您可以通过do {BLOCK} 将块嵌入到表达式中,但这不会完全满足您的要求。

如果你想表达“如果列表中的任何项目匹配,则操作文件名”,这样做

if (grep { $File::Find::name =~ /$_/ } LIST) { ... }

如果你想表达“如果列表的所有项目都匹配,则操作文件名”,这样做

if (not grep { not $File::Find::name =~ /$_/ } LIST) { ... }

您不能像@array[0..-2] 这样对数组进行切片,因为范围运算符在数组下标中并不特殊;从 0 到 -2 的范围为空。而是:@array[0 .. @array-2]

【讨论】:

  • 谢谢,not grep 正是我所需要的。看到@array[0..@array-2] 的语法非常有趣。我已经定义了一个要使用的变量:my $largv=@ARGV-2; @ARGV[0..$largv],它的工作原理类似。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-16
  • 2011-12-28
  • 2018-12-31
相关资源
最近更新 更多