Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在正则表达式中使用交替时,Perl未初始化值_Regex_Perl_Alternation_Regex Alternation - Fatal编程技术网

Regex 在正则表达式中使用交替时,Perl未初始化值

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[

我有一个带有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[$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;