现在遇到脚本问题。 试图过滤掉文件的某些部分并将它们放入标量中。这是代码。
@value = (grep {m/(III[ABC])/g and m//g }<$fh>)
print @value;
@value = (grep { m/[012]iii/g}(<$fh>));
print @value;
当我运行第一个grep
时,值会显示在打印参数中。但是当我运行第二个grep
时。第二个打印语句不打印任何内容。添加第二个grep,取消第一个grep的有效性吗?
我知道第一次和第二次grep工作,因为即使我评论了第一个grep。第二个grep函数工作。 我真正想要做的就是过滤掉多个不同的单个阵列的信息。我真的很困惑如何解决这个问题,因为我打算在脚本中添加更多的grep。
答案 0 :(得分:4)
<$fh>
上的第一次读取到达文件的末尾。然后第二次调用无需阅读。因此,如果你注释掉第一个,那么这并不会发生,第二个就会起作用。
下面的代码添加到同一个数组中。如果需要,请更改为注释掉的代码。正则表达式是简化的,因为它不需要注释而它不会影响实际问题。请把它放回原来的样子,如果那是你的真实含义。
您可以在读完所有行后回放文件句柄
my @vals = grep { /III[ABC]/ } <$fh>;
seek $fh, 0, 0;
# ready for reading again from the beginning
push @vals, grep { /[012]iii/ } <$fh>;
#or: my @vals_2 = grep { /[012]iii/ } <$fh>;
或者您可以将所有行读入数组,然后然后重复处理。
my @original = <$fh>;
my @vals = grep { /III[ABC]/ } @original;
push @vals, grep { m/[012]iii/ } @original;
# or assign to a different array
如果您不需要按照这样的顺序存储这些结果,那么逐行读取文件并进行处理和添加会更有效率。
<强>更新强>
我简化了最初发布的正则表达式,以便专注于手头的问题,因为块内的确切条件与它无关。请参阅下面的注释。感谢ikegami提出并解释//
&#34; 重复上次成功的查询&#34;。
m//g
很棘手,我将其删除了。grep
检查条件并在条件评估为真时传递一条直线。在这样的标量上下文中,/.../g
修饰符的效果是一个非常不同的故事,已删除。()
是不需要的(过量)。 m/
。有关正则表达式的说明
在标量上下文中/.../g
修饰符按perlrequick执行以下操作:
对字符串的连续匹配将// g从匹配跳转到匹配
空字符串模式m//g
也具有很明显的效果,如上所述。
总之,这些在我的测试中产生了非平凡的结果,需要精神追踪才能理解。我把它们从这里的代码中删除了,因为它们会引起一个问题,即它们是否是故意的诡计或微妙的错误,从而分散了实际的问题 - 它们完全没有影响。
答案 1 :(得分:2)
我不知道您对g
修饰符的看法,但这里没有任何意义。
我不知道你的想法是什么//
(与空模式相匹配),但这里没有任何意义。
在列表上下文中,<$fh>
返回文件中的所有剩余行。第二次评估它时,它不返回任何内容,因为您第一次评估它时已经到达文件的末尾。
修正:
my @lines = <$fh>;
my @values1 = grep { /III[ABC]/ && /.../ } @lines;
my @values2 = grep { /[012]iii/ } @lines;
当然,请将...
替换为您在那里使用的内容。