Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.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 - Fatal编程技术网

Regex 在perl中,如何查找不带';不符合模式

Regex 在perl中,如何查找不带';不符合模式,regex,perl,Regex,Perl,我需要找到这方面的补充: $_ = 'aaaaabaaabaaabacaaaa'; while( /([a][a][a][a])/gc){ next if pos()%4 != 0; my $b_pos = (pos()/4)-1; print " aaaa at :$b_pos\n"; } 也就是说,一组4个字符不是“aaaa” 下面的方法不起作用 $_ = 'aaaaabaaabaaabacaaaa'; while( /([^a][^a][^a][^a])/gc

我需要找到这方面的补充:

$_ = 'aaaaabaaabaaabacaaaa';

while( /([a][a][a][a])/gc){
    next if pos()%4 != 0;
    my $b_pos = (pos()/4)-1;
    print " aaaa at :$b_pos\n";
}
也就是说,一组4个字符不是“aaaa”
下面的方法不起作用

$_ = 'aaaaabaaabaaabacaaaa';

while( /([^a][^a][^a][^a])/gc){
    my $b_pos = (pos()/4)-1;
    print "not a at :$b_pos\n";
}
我当然能做到

$_ = 'aaaaabaaabaaabacaaaa';

while( /(....)/gc){
    next if $1 eq 'aaaa';
    my $b_pos = (pos()/4)-1;
    print "$1 a at :$b_pos\n";
}
难道没有更直接的方法吗

为了澄清预期结果,我需要找到所有不是“aaaa”的4个字母组合以及它们的位置。
第一代码输出

 aaaa at :0
 aaaa at :4
应该输出第二个代码

not aaaa at :1
not aaaa at :2
not aaaa at :3
第三个代码输出,是我要找的

abaa at :1
abaa at :2
abac at :3
我知道我还不够清楚,请接受我的回复。
我试图实现的是将一个字符串分成4个字母的组,得到与模式不匹配的组的值和位置

我的第三个代码给出了预期的结果。它同时读取字符串4个字母,并处理那些不是“aaaa”的字母。
感谢大家的建议,我还发现我的第一个代码没有按预期工作,如果pos()%4!=0,这意味着模式跨越两组4。我更正了代码。

与我和其他人的所有期望相反,以下内容根本没有输出任何东西

/[^a]{4}/
我可能应该坚持我的第三个代码

/(?!aaaa)/
这是一个负前瞻,在模式
aaaa
不匹配的第一个位置匹配

或者

/[^a]{4}/
将所有非
a
的4个字符匹配在一起

这是一个负前瞻,在模式
aaaa
不匹配的第一个位置匹配

或者

/[^a]{4}/
将4个字符匹配在一起,这些字符都不是
a

这个怎么样:

/[^a]{4}/
这个怎么样:

/[^a]{4}/
委员会:

委员会:

试试这个:

/(?:(?!aaaa)[a-z]){4}/g
在匹配每个字符之前,先行检查确保它们不是
aaaa

请尝试以下操作:

/(?:(?!aaaa)[a-z]){4}/g

在匹配每个字符之前,先行检查确保它们不会被
aaaa

编辑:经过进一步的修改并认为我找到了正确的解决方案后,我将保留前面的答案供参考

似乎/aaaa(?!aaaa)…|(?!aaaa)../gc是/aaaa/的补充,用于您的目的:

$_ = 'aaaaabaaabaaabacaaaa';
while( /aaaa(?!aaaa)....|(?!aaaa)..../gc ){
    my $b_pos = (pos()/4)-1;
    print substr($_,$b_pos*4,4)." at :$b_pos\n";
}
结果是:

abaa at :1
abaa at :2
abac at :3

先前的答案

即使在小样本输入中,负前瞻也不会与“块”迭代交互:

use POSIX floor;
$_ = 'aaaaabaaabaaabacaaaa';
while( /(?!aaaa)..../gc ){
    my $b_pos = floor(pos()/4);
    print " !aaaa at :$b_pos str:".substr($_,$b_pos*4,4);
    print " c_pos:".(pos()-4)." str:".substr($_,(pos()-4),4)."\n";
}
输出:

 !aaaa at :1 str:abaa c_pos:2 str:aaab
 !aaaa at :2 str:abaa c_pos:6 str:aaab
 !aaaa at :3 str:abac c_pos:10 str:aaab
 !aaaa at :4 str:aaaa c_pos:14 str:acaa
这是因为前瞻将逐字符计算,而不是以4块为单位。这意味着在AAAAA的情况下,它将先检查aaaa,然后再检查aaab,因为aaaa与aaaa不匹配,因此这些将被消耗,而不是人们可能希望的baaa

然而,明智地使用map、grep和split解决了问题:

my $c = 0;
print "!aaaa at positions: ", 
      join ",", map { $$_[1] } 
                    grep { $$_[0] !~ /aaaa/ } 
                         map { [$_, $c++ ] } 
                             grep /./, split /(.{4})/, $_;
print "\n";
结果:

!aaaa at positions: 1,2,3
说明:

  • split/(.{4})/,$将把输入分割成4个字符的块列表
  • 但是,在split中使用regexp capture可能会导致列表中出现空块,因此我们使用grep/消除它们/
  • 现在我们创建输入的元组加上块号(因此我们需要一个初始化为0的$c…)
  • 现在我们筛选与“aaaa”不匹配的元素
  • 现在我们只需映射以检索块编号
  • 要匹配您的精确输出,请执行以下操作:


    编辑:经过更多的修改和思考,我找到了正确的解决方案,我将留下前面的答案供参考

    似乎/aaaa(?!aaaa)…|(?!aaaa)../gc是/aaaa/的补充,用于您的目的:

    $_ = 'aaaaabaaabaaabacaaaa';
    while( /aaaa(?!aaaa)....|(?!aaaa)..../gc ){
        my $b_pos = (pos()/4)-1;
        print substr($_,$b_pos*4,4)." at :$b_pos\n";
    }
    
    结果是:

    abaa at :1
    abaa at :2
    abac at :3
    

    先前的答案

    即使在小样本输入中,负前瞻也不会与“块”迭代交互:

    use POSIX floor;
    $_ = 'aaaaabaaabaaabacaaaa';
    while( /(?!aaaa)..../gc ){
        my $b_pos = floor(pos()/4);
        print " !aaaa at :$b_pos str:".substr($_,$b_pos*4,4);
        print " c_pos:".(pos()-4)." str:".substr($_,(pos()-4),4)."\n";
    }
    
    输出:

     !aaaa at :1 str:abaa c_pos:2 str:aaab
     !aaaa at :2 str:abaa c_pos:6 str:aaab
     !aaaa at :3 str:abac c_pos:10 str:aaab
     !aaaa at :4 str:aaaa c_pos:14 str:acaa
    
    这是因为前瞻将逐字符计算,而不是以4块为单位。这意味着在AAAAA的情况下,它将先检查aaaa,然后再检查aaab,因为aaaa与aaaa不匹配,因此这些将被消耗,而不是人们可能希望的baaa

    然而,明智地使用map、grep和split解决了问题:

    my $c = 0;
    print "!aaaa at positions: ", 
          join ",", map { $$_[1] } 
                        grep { $$_[0] !~ /aaaa/ } 
                             map { [$_, $c++ ] } 
                                 grep /./, split /(.{4})/, $_;
    print "\n";
    
    结果:

    !aaaa at positions: 1,2,3
    
    说明:

  • split/(.{4})/,$将把输入分割成4个字符的块列表
  • 但是,在split中使用regexp capture可能会导致列表中出现空块,因此我们使用grep/消除它们/
  • 现在我们创建输入的元组加上块号(因此我们需要一个初始化为0的$c…)
  • 现在我们筛选与“aaaa”不匹配的元素
  • 现在我们只需映射以检索块编号
  • 要匹配您的精确输出,请执行以下操作:


    顺便说一句,
    [a][a][a][a]
    可以写成
    aaaa
    我同意,这是为了澄清,我不明白你所说的pos()/4-1是什么意思。。。你真的不是指pos()-4??!反过来又是什么呢?你真的想让所有的位置占据接下来的4个字符吗?它们不是“aaaa”?我想做的是一次读取一个字符串4个字符,当它与“aaaa”不匹配时获取它的位置,但我还需要捕获它的值以便进一步处理。所以(pos()/4)-1给了我从0开始的位置,这对我以后更方便。所以你的位置实际上是“4个字符组的计数…”顺便说一句,
    [a][a][a]
    可以写成
    aaaa
    我同意,这是为了澄清,我不明白你所说的pos()/4-1是什么意思。。。你真的不是指pos()-4??!反过来又是什么呢?你真的想让所有的位置占据接下来的4个字符吗?它们不是“aaaa”?我想做的是一次读取一个字符串4个字符,当它与“aaaa”不匹配时获取它的位置,但我还需要捕获它的值以便进一步处理。所以(pos()/4)-1给了我从0开始的位置,这对我以后更方便。所以你的位置实际上是“4个字符组的计数…”这是我一开始的想法,但这些都没有给我预期的结果result@kaklon根据问题的当前形式,这是正确答案-如果这不是您想要的,也许你应该多解释一下。添加一些示例字符串