为什么 perl 中的这个正则表达式适用于一个单词而不是另一个单词?



我是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
[^
  1. 为什么打印线条顺序不对? 由于"stuff"行出现在文件的后面,它不应该稍后打印吗?

  2. 为什么打印第二行是错误的? 它应该是"(([^"。 它缺少前 3 个字符。

  3. 如果我将正则表达式更改为以下内容:/directory(([^)]*))/,则没有输出。 唯一的区别是这个词。 它应该找到第二条评论。 这是怎么回事?

  1. 如果你刚刚开始学习Perl,use 5.006有点奇怪......这是一个古老的版本。

  2. 您不应该在当前目录下的所有位置构建一个潜在的庞大列表,然后对其进行过滤。相反,请仅将所需的文件推送到列表中。

  3. 特别是对于转义的元字符,正则表达式模式可能很快变得难以阅读,因此请使用/x修饰符在这些模式中插入一些空格。

  4. 您不必匹配两次:只需同时检查和捕获即可。

  5. 如果open失败,请在错误消息中包含原因。

  6. 你上面的第二个问题没有意义。你似乎希望你的模式与文字字符串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

最新更新