我是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 "$substringn" if $substring;
}
}
close $fh;
}
# file(stuff)
# directory(stuff)
现在,当我运行它时,我得到以下输出:
stuff
[^
为什么打印线条顺序不对? 由于"stuff"行出现在文件的后面,它不应该稍后打印吗?
为什么打印第二行是错误的? 它应该是"
(([^
"。 它缺少前 3 个字符。如果我将正则表达式更改为以下内容:
/directory(([^)]*))/
,则没有输出。 唯一的区别是这个词。 它应该找到第二条评论。 这是怎么回事?
-
如果你刚刚开始学习Perl,
use 5.006
有点奇怪......这是一个古老的版本。 -
您不应该在当前目录下的所有位置构建一个潜在的庞大列表,然后对其进行过滤。相反,请仅将所需的文件推送到列表中。
-
特别是对于转义的元字符,正则表达式模式可能很快变得难以阅读,因此请使用
/x
修饰符在这些模式中插入一些空格。 -
您不必匹配两次:只需同时检查和捕获即可。
-
如果
open
失败,请在错误消息中包含原因。 -
你上面的第二个问题没有意义。你似乎希望你的模式与文字字符串
file(([^)]*))/
匹配,但它不能。
use strict;
use warnings;
use File::Find;
my @files;
find(
sub {
return if -d;
return unless / [.] pl z/x;
push @files, $File::Find::name;
},
'.',
);
for my $file ( @files ) {
open my $fh, '<', $file
or die "Could not open file $file: $!";
while (my $line = <$fh>) {
if (my ($substring) = ($line =~ m{ (?:file|directory) ( ([^)]*) ) }x)) {
print "$substringn";
}
}
close $fh;
}
# file(stuff)
# directory(other)
输出:
stuff
other