【发布时间】:2017-08-24 18:26:45
【问题描述】:
我是 perl 新手,所以如果我的问题看起来很明显,请原谅。我制作了一个小的 perl 脚本,它只检查自身以提取我正在寻找的特定子字符串,并且得到了我无法解释的结果。这是脚本:
use 5.006;
use strict;
use warnings;
use File::Find;
my @files;
find(
sub { push @files, $File::Find::name unless -d; },
"."
);
my @filteredfiles = grep(/.pl/, @files);
foreach my $fileName (@filteredfiles)
{
open (my $fh, $fileName) or die "Could not open file $fileName";
while (my $row = <$fh>)
{
chomp $row;
if ($row =~ /file/)
{
my ($substring) = $row =~ /file\(([^\)]*)\)/;
print "$substring\n" if $substring;
}
}
close $fh;
}
# file(stuff)
# directory(stuff)
现在,当我运行它时,我得到以下输出:
stuff
[^\
为什么会乱序打印行?由于“stuff”行出现在文件的后面,不应该稍后打印吗?
为什么第二行打印错误?它应该是“
\(([^\”。它缺少前 3 个字符。如果我将正则表达式更改为以下内容:
/directory\(([^\)]*)\)/,我将没有输出。唯一的区别是单词。它应该找到第二条评论。这是怎么回事?
【问题讨论】:
-
您是否也更改了围绕它的
if块的条件? -
对我来说,这只是打印
stuff,而不是[^\。由于file和(之间的反斜杠,正则表达式无法匹配自身!您在同一目录中是否有任何其他文件名包含pl?可能是同一脚本的先前版本? -
好的,这是一个显而易见的答案,我在过去的一个小时里一直在努力反对。不,我忘了更改 if 语句。谢谢你。至于第二条评论,不,我在目录中没有任何其他 pl 文件。
-
请注意,
/.pl/匹配包含任何字符后跟pl的任何单词,例如单词example。.不是文字点,而是匹配任何(非换行符)字符。正则表达式未锚定为仅在末尾匹配。您可能打算/\.pl$/过滤文件名。由于字符序列[^\相当独特,可能它们来自先前版本脚本的隐藏备份文件? -
我上面评论中的
if (...)将捕获存储在$substr变量中,然后在{ ... }和if分隔的范围内可用。所以是的,你在$substr中有'catch'。你是这个意思吗?查看@Sinan 的完整答案。