Regex 在正则表达式中使用交替时,Perl未初始化值
我有一个带有if语句的for循环,如下所示:Regex 在正则表达式中使用交替时,Perl未初始化值,regex,perl,alternation,regex-alternation,Regex,Perl,Alternation,Regex Alternation,我有一个带有if语句的for循环,如下所示: for (my $i=0; $i < $size; $i++) { if ($array[$i] =~ m/_(B|P|BC|PM)/) { #Remove from @array splice(@array, $i, 1); next; } #Get rid of numbers at the end $array[
for (my $i=0; $i < $size; $i++) {
if ($array[$i] =~ m/_(B|P|BC|PM)/) {
#Remove from @array
splice(@array, $i, 1);
next;
}
#Get rid of numbers at the end
$array[$i] =~ s/_[0-9]+//;
}
for(我的$i=0;$i<$size;$i++){
if($array[$i]=~m/(B | P | BC | PM)/){
#从@array中删除
拼接(@array,$i,1);
下一个
}
#去掉结尾的数字
$array[$i]=~s/[0-9]+/;
}
我得到一个错误,在if语句的行上写着“在模式匹配中使用@array中的未初始化值…”
当我从该行的正则表达式中删除替换项时,错误就消失了。如果我注释掉整个If语句,注释“#去掉末尾的数字”下的正则表达式不会产生任何错误
我已经打印出@array的所有值,一切看起来都很好。我尝试了不使用括号和括号,而不是表达式中的括号,没有任何更改。你知道是什么导致了这个问题吗?这里是同一问题的简单演示
1: @array = (1,2);
2: $size = 2;
3: for ($i=0; $i<$size; $i++) {
4: if ($array[$i] == 1) {
5: splice @array, $i, 1;
6: }
7: }
也就是说,识别满足某些条件的
@array
的所有元素(这里的条件与模式不匹配),然后更新@array
,使其只保存那些好的元素。zdim还有另一个很好的方法。从数组中删除元素原则上是昂贵的,尽管splice
优化有帮助。谢谢你的评论。更重要的是,正确地处理这些指数需要很多小心,正如暴民的回答中所揭示和剖析的那样。这是另一种方法
my @new_array =
map {
s/_[0-9]+//; #/ cleanup from the last statement in loop
$_ # return this element, not return of s/../../
}
grep { defined && !/_(B|P|BC|PM)/ } # remove elements
@array;
首先grep
确保跳过undef
元素,然后过滤您需要的内容。它的输出列表作为输入传递给映射
,从而将循环的最后一行更改为每个元素
如果您不关心旧数组,只需将其分配给@array
,而不是创建一个@new\u数组
首先,我们可以在替换中使用非破坏性的/r
修饰符,它返回已更改的字符串并保持原始字符串不变。这是一个完美的用例
@array = map { s/_[0-9]+//r } grep { defined && !/_(B|P|BC|PM)/ } @array;
其中原始数组被覆盖
这将对数据进行两次处理。一个更有效的版本是在数组上循环,并将要保留的元素适当地更改(复制)到新数组中。通过“删除替换”,我的意思是我将正则表达式更改为“$array[$I]=~m/\u B/”。哦,是的,我每次都需要减小$size,谢谢,仅仅减小$size是不够的;移除一个元素后,您仍然会跳过对该元素的处理。您还需要减少$i
@mob或redo,而不是下一步。从数组中移除元素并不那么昂贵。它的费用与剩余元素的数量有关,而不是与这些元素的大小有关映射s/[0-9]+///r,grep…
@ysth好的,当然。我想到的是一个任意数组,其中一个可能会从中间删除很多很多元素。我不知道可以进行哪些优化(特别是通过拼接
),但我担心数据拷贝(完整数组分配)可能会按照数组大小的顺序进行多次。这只是最坏的情况,但我仍然不喜欢它的复杂性。@ysth啊,当然!我只是在另一个答案中使用它。。。谢谢,添加:)push/pop/shift/unshift/splice都经过了很好的优化,可以尽可能少地将指针移动到周围的元素,并且它们根本不接触保留的实际数据
@array = map { s/_[0-9]+//r } grep { defined && !/_(B|P|BC|PM)/ } @array;