我想拆分一个字符串(有数字)。在下面的示例中,我想将字符串拆分为k和k1。
my @array1=("0","23","1","4","65","7");
$k=1;$k1=0;
my $j=join("",@array1);
my @ar=split(/($k|$k1)/,$j);
print join(";",@ar),"\n\n";
输出为;0;23;1;4657
在上面的输出中,额外的分号“;”正在打印
预期输出为0;23;1;4657
当我为以下示例尝试上面的代码时,输出是正确的:(0;5;123;4;6)
;额外的分号不在这里打印。
my @array1=("0","5","1234","6");
$k=5;$k1=4;
我不确定,出于什么原因,第一个例子是打印额外的分号“;”
有人可以帮助我吗?
答案 0 :(得分:2)
不同之处在于当你分开第一个字符时,你会在开头得到一个空值。因此额外;在0之前(和“”之后)。你会同样找到;;拆分两个相邻的字符时
所以绝对最简单的修复方法是使用grep删除空字符串:
my @ar=split(/($k|$k1)/,$j);
@ar = grep /./, @ar;
这将删除@ar。
中的空字符串从更大的角度来看,你可能想看看为什么你要加入字符串只是为了将它们分开。你也在一个地方分裂,可能出现在另一个地方。就像$ k = 1和@ array1 =(11,23,1,4);
答案 1 :(得分:1)
这是一个非常人为的例子,有很多问题(例如$ k和$ k1需要用“my”声明,你应该use strict
等)并且它可能会做你不做的事情想。
底线以及您看到前导分号的原因是,如果您使用在字符串开头匹配的分隔符进行拆分,split将返回一个空列表元素。
print join ';', split /0/, '0123';
答案 2 :(得分:1)
在这段代码中有一些有趣的行为我不知道,并且在其他答案中没有提到。正则表达式上split
通常会发生的事情是,您要拆分的字符将从结果中省略。但是,似乎如果在正则表达式中捕获括号,则捕获的材料将保留在结果中。
#!/usr/bin/env perl
use strict;
use warnings;
my @array1 = ("0", "23", "1", "4", "65", "7");
my $j = join("", @array1);
my $k;
my $k1;
my @ar;
print "Join [$j]\n";
$k = 1;
$k1 = 0;
printf "%-25s", "Version 1 /($k|$k1)/:";
@ar = split(/($k|$k1)/, $j);
print "[", join(";", @ar), "]\n";
printf "%-25s", "Version 2 /($k|$k1)/:";
$k = "1";
$k1 = "0";
@ar = split(/($k|$k1)/, $j);
print "[", join(";", @ar), "]\n";
printf "%-25s", "Version 3 /[01]/:";
@ar = split(/[01]/, $j);
print "[", join(";", @ar), "]\n";
printf "%-25s", "Version 4 /(0|1)/:";
@ar = split(/(0|1)/, $j);
print "[", join(";", @ar), "]\n";
printf "%-25s", "Version 5 /0|1/:";
@ar = split(/0|1/, $j);
print "[", join(";", @ar), "]\n";
printf "%-25s", "Version 6 /([46])/:";
@ar = split(/([46])/, $j);
print "[", join(";", @ar), "]\n";
printf "%-25s", "Version 7 /(?:[46])/:";
@ar = split(/(?:[46])/, $j);
print "[", join(";", @ar), "]\n";
Join [02314657]
Version 1 /(1|0)/: [;0;23;1;4657]
Version 2 /(1|0)/: [;0;23;1;4657]
Version 3 /[01]/: [;23;4657]
Version 4 /(0|1)/: [;0;23;1;4657]
Version 5 /0|1/: [;23;4657]
Version 6 /([46])/: [0231;4;;6;57]
Version 7 /(?:[46])/: [0231;;57]
如您所见,当分割字符串的正则表达式中存在捕获括号时,将保留(捕获的)分割字符。如果括号丢失或明确无法捕获(版本7),则不会保留拆分字符。
而且,如果您仔细阅读本手册,split
说明确实包含以下段落:
如果PATTERN包含capturing groups,则对于每个分隔符,将为组捕获的每个子字符串生成一个附加字段(按照backreferences的顺序指定组的顺序;如果任何组都不匹配,然后它捕获
undef
值而不是子字符串。另外,请注意,只要有分隔符(即,每当发生拆分时)都会产生任何此类附加字段,并且这样的附加字段不计入LIMIT。
接下来是一些例子。
在Mac OS X 10.7.5上使用Perl 5.16.0进行测试。
答案 3 :(得分:1)
一种选择是使用正则表达式而不是split
。这适用于您显示的两个数据集:
use strict;
use warnings;
my @array1 = ( "0", "23", "1", "4", "65", "7" );
my $k = 1;
my $k1 = 0;
my $j = join( '', @array1 );
my @ar = $j =~ /([$k$k1]|[^$k$k1]+)/g;
print join( ";", @ar );
输出:
0;23;1;4657
答案 4 :(得分:0)
Perl提供了一个非常强大的正则表达式替换构造,在这种情况下不需要执行split
- fu和join
- fu:
$string =~ s{(?:$k|$k1)\K}{;}g ;