regex - 文件句柄第二次读取失败
问题描述
如何foreach
在 Perl 的循环中第二次从文件句柄中读取?
foreach $a (@b){
while(my $line = <IN>){
if($line = /$a/){
print $line;
}
}
}
上面的代码没有处理 list 中的第二个元素@b
。如何使它成为可能?
解决方案
你的内部循环,while(my $line = <IN>)
从句柄中提取行,IN
直到它到达文件的末尾。
当您的外部循环 ,foreach $a (@b)
尝试再次读取IN
时,它仍处于文件末尾。循环的第一次迭代foreach
消耗了文件中的所有行,没有为其他迭代留下任何内容。
有几种可能的方法来解决这个问题:
在尝试
IN
再次读取之前,请回到开头:foreach $a (@b){ seek IN, 0, 0 or die "Cannot seek(): $!"; while (my $line = <IN>) { ... } }
但是,这仅适用于真实文件,不适用于管道、套接字或终端。
预先将整个文件读入内存,然后遍历一个普通数组:
my @lines = <IN>; foreach $a (@b){ foreach my $line (@lines) { ... } }
但是,如果文件很大,这将占用大量内存。
切换两个循环的顺序:
while (my $line = <IN>) { foreach $a (@b) { ... } }
这是我最喜欢的。现在您只需要从文件中读取一次。
@b
已经在内存中,因此您可以根据需要多次迭代它。
旁注:
- 不要使用裸字文件句柄,如
IN
. 普通变量(例如$IN
)在各个方面都非常出色。 - 不要使用名为
$a
or的变量$b
。它们有点特别,因为 Perl 在sort
. - 我个人的偏好是永远不要使用
< >
. 它奇怪地超载(它可以表示readline
或glob
,具体取决于您使用的确切语法)并且它不是非常直观。使用readline
意味着永远不会有任何语法歧义,即使没有 Perl 经验的程序员也能弄清楚它的作用。
随着这些变化:
while (my $line = readline $IN) {
foreach my $re (@regexes) {
if ($line =~ /$re/) {
print $line;
}
}
}
推荐阅读
- flutter - 即使在删除 Permission Handler Plugin 后,Flutter App 仍在请求权限
- python-3.x - python3中的嵌套循环
- python - 给定一列一行作为坐标填充数据框
- java - 模拟 HttpHeaders 抛出 NullPointerException
- python - 将一个数组的值映射到另一个数组
- javascript - 如果用户直接将其输入 URL,如何处理存在字节的 React 中的路由可能没有数据
- python - 从 Postgres 表创建 XML 树结构
- java - 删除前导零,但留下一个必要的 From String in Java
- r - 在 mutate 中引用具有相似模式的列
- excel - 使用变量 VBA 调用表单/模块