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
说明:
编辑:经过更多的修改和思考,我找到了正确的解决方案,我将留下前面的答案供参考 似乎/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
说明:
顺便说一句,
[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根据问题的当前形式,这是正确答案-如果这不是您想要的,也许你应该多解释一下。添加一些示例字符串