我有一个二进制数,例如10000111000011
,并希望将其拆分为连续的1和0,1 0000 111 0000 11
组。
我认为这是一个很好的机会来使用环视:我的正则表达式使用一个正数的后视数字(它捕获以供以后反向引用),然后是相同数字的负面预测(使用一个反向引用),所以每当一个数字后跟一个不相同的数字时,我就会得到一个分裂。
use strict;
use warnings;
use feature 'say';
my $bin_string = '10000111000011';
my @groups = split /(?<=(\d))(?!\g1)/, $bin_string;
say "@groups";
然而,这会导致
1 1 0000 0 111 1 0000 0 11 1
不知何故,每次拆分时都会插入捕获的数字。出了什么问题?
答案 0 :(得分:2)
以下是代码的小修补程序:
my @groups = split /(?<=0(?!0)|1(?!1))/, $bin_string;
您遇到的问题是,使用split
时,捕获的文本也会在结果数组中输出。因此,解决方案是摆脱捕获组。
由于您的输入中只有0
或1
,因此可以通过更改和前瞻来确保数字发生变化。
请参阅demo
答案 1 :(得分:1)
只是做匹配而不是分裂。
(\d)\1*
示例:
use strict;
use warnings;
use feature 'say';
my $bin_string = '10000111000011';
while($bin_string =~ m/((\d)\2*)/g) {
print "$1\n";
}
答案 2 :(得分:1)
(?<=0)(?=1)|(?<=1)(?=0)
简单地由此分开。参见演示。
https://regex101.com/r/fM9lY3/3
lookarounds
会找到落后0
且前方1
或1
落后且0
落后的位置。因此导致正确拆分而不消耗任何东西。