我的问题与How do I re.search or re.match on a whole file without reading it all into memory?的问题相同,但使用的是perl而不是python
问题: 我希望能够在整个文件上运行正则表达式,但我希望能够不必立即将整个文件读入内存,因为我可能正在使用相当大的文件未来。有没有办法做到这一点?谢谢!
澄清:我无法逐行阅读,因为它可以跨越多行。
为什么我使用perl而不是python?我已经遇到了python正则表达式的足够问题,我需要切换到perl。我会安装https://pypi.python.org/pypi/regex,但我不能,因为我的工作场所,可以理解,不允许写入其python安装目录,我宁愿避免使用IT来实现缓慢的来回电子邮件链他们为我安装,和/或处理进一步的许可问题:)
编辑:示例模式我正在寻找
assign signal0 = (cond1) ? val1 :
(cond2) ? val2 :
val3;
assign signal1[15:0] = {input1[7:0], input2[7:0]};
assign signal2[34:0] = { 4'b0,
subsig0[3:0],
subsig1,
subsig2,
subsig3[18:2],
subsig4[5:0]
};
我正在寻找类似上面的模式,即在看到分号之前进行变量分配。正则表达式将与上述任何一个匹配,因为我不知道该模式是否是多行的。也许类似于/assign\s+\w+\s+=\s+[^;];/m
,即直到我看到分号
EDIT2:从给定的答案(谢谢!)看来,将模式分解为开始,中间和&结束部分可能是最佳策略,例如根据一些人的建议使用范围运算符。
答案 0 :(得分:4)
您可以使用range operator来匹配两个模式之间的所有内容,同时逐行阅读:
use strict;
use warnings 'all';
while (<DATA>) {
print if /^assign / .. /;/;
}
__DATA__
foo
assign signal0 = (cond1) ? val1 :
(cond2) ? val2 :
val3;
bar
assign signal1[15:0] = {input1[7:0], input2[7:0]};
baz
assign signal2[34:0] = { 4'b0,
subsig0[3:0],
subsig1,
subsig2,
subsig3[18:2],
subsig4[5:0]
};
qux
输出:
assign signal0 = (cond1) ? val1 :
(cond2) ? val2 :
val3;
assign signal1[15:0] = {input1[7:0], input2[7:0]};
assign signal2[34:0] = { 4'b0,
subsig0[3:0],
subsig1,
subsig2,
subsig3[18:2],
subsig4[5:0]
};
答案 1 :(得分:3)
您可以将输入记录分隔符$/
设置为分号;
并逐行读取。每行都将在声明中,包括尾随分号。然后匹配变得微不足道。
答案 2 :(得分:2)
我可以想象两种解决方案(没有大量思考,所以也许我错了):
a)使用最大匹配字符数,例如1024. 1)读入两倍(2048)个字符。 2)尝试匹配。 3)向前搜索1024个字符。重复。
b)使用匹配在单行中的起始和结束模式。之间的部分可以在以后测试。 Perl的触发器操作符可以在这种情况下使用。
编辑:由于问题得到了更新,解决方案b)似乎很好。
起始模式是赋值,结束模式是分号。中间的所有内容都可以连接在一起,然后进行有效性测试。
示例:
my $assignment = "";
while (<>) {
if (/assign\s+\w+\s+=/ .. /;/) {
$assignment .= $_;
} else {
if ($assignment =~ /full regex/) {
# do something with the match
}
$assignment = "";
}
}
答案 3 :(得分:1)
以下是使用渐进式匹配和预匹配模式的示例:
use feature qw(say);
use strict;
use warnings;
my $pre_match = qr{assign\s+\S+\s+=\s+};
my $regex = qr{($pre_match[^;]+;)};
my $line = "";
my $found_start = 0;
while( <DATA> ) {
if ( !$found_start && /$pre_match/ ) {
$line = "";
$found_start = 1;
}
if ( $found_start ) {
$line .= $_;
if ( $line =~ /$regex/ ) {
say "Got match: '$1'";
$found_start = 0;
$_ = substr $line, $+[0];
redo;
}
}
}
__DATA__
assign signal0 = (cond1) ? val1 :
(cond2) ? val2 :
val3;
assign signal1[15:0] = {input1[7:0], input2[7:0]};
assign signal2[34:0] = { 4'b0,
subsig0[3:0],
subsig1,
subsig2,
subsig3[18:2],
subsig4[5:0]
};
<强>输出强>:
Got match: 'assign signal0 = (cond1) ? val1 :
(cond2) ? val2 :
val3;'
Got match: 'assign signal1[15:0] = {input1[7:0], input2[7:0]};'
Got match: 'assign signal2[34:0] = { 4'b0,
subsig0[3:0],
subsig1,
subsig2,
subsig3[18:2],
subsig4[5:0]
};'