【问题标题】:Why does split return an array with every second element empty?为什么 split 返回一个每隔一个元素为空的数组?
【发布时间】:2014-12-14 15:06:38
【问题描述】:

我正在尝试每 5 个字符拆分一个字符串。我从split 返回的数组不是我所期望的:所有偶数索引都是空的,我要查找的部分是奇数索引。

这个版本不输出任何东西:

use warnings;
use strict;
my @ar = <DATA>;
foreach (@ar){
    my @mkh = split (/(.{5})/,$_);
    print $mkh[2];
}
__DATA__
aaaaabbbbbcccccdddddfffff

如果我用这个替换print 行(奇数索引13):

 print $mkh[1],"\n", $mkh[3];

输出是前两部分:

aaaaa
bbbbb

我不明白这个,我希望能够用这个打印前两部分:

print $mkh[0],"\n", $mkh[1];

谁能解释我的代码有什么问题,并帮我修复它?

【问题讨论】:

  • 谁投反对票请添加评论。

标签: perl split


【解决方案1】:

split 中的第一个参数是要拆分的模式,即它描述了分隔字段的内容。如果您将捕获组放入其中(如您所做的那样),它们将被添加到 split 文档(最后一段)中指定的拆分输出中。

这不是您想要的 - 您的分隔符不是一组五个字符。您希望每隔 X 个字符拆分一个字符串。为此,更好地使用:

my @mkh = (/...../g);
# or
my @mkh = (/.{5}/g);

或您将在以下位置找到的其他选项之一:How can I split a string into chunks of two characters each in Perl?

【讨论】:

  • 我编辑了我的脚本,但 Use of uninitialized value in print at line 5 没有工作错误。
  • 如果我将脚本中的那一行替换为我在帖子中的内容,我不会收到任何警告,并且会输出ccccc(没有换行符)。确保您已按原样复制。
  • 对不起。这是工作。我错过了g 全球比赛。所以它没有给出输出
  • @Mat 请考虑编辑问题,因为您似乎能够理解它(我不明白)。
  • @ivan_pozdeev:现在好些了吗?标题可能需要更多工作......但我没有找到更短的内容。
【解决方案2】:

使用 Data::Dump 进行调试

要准确观察您的split 操作在做什么,请使用Data::Dump 之类的模块:

use warnings;
use strict;

while (<DATA>) {
    my @mkh = split /(.{5})/;

    use Data::Dump;
    dd @mkh;
}
__DATA__
aaaaabbbbbcccccdddddfffff

输出:

("", "aaaaa", "", "bbbbb", "", "ccccc", "", "ddddd", "", "fffff", "\n")

如您所见,您的代码以 5 个字符为一组进行拆分,并在它们之间留下空字符串。这显然不是你想要的。

改用模式匹配

相反,您只想捕获 5 个字符的组。因此,您只需要与/g Modifier 进行模式匹配:

use warnings;
use strict;

while (<DATA>) {
    my @mkh = /(.{5})/g;

    use Data::Dump;
    dd @mkh;
}
__DATA__
aaaaabbbbbcccccdddddfffff

输出:

("aaaaa", "bbbbb", "ccccc", "ddddd", "fffff")

【讨论】:

    【解决方案3】:

    你也可以使用零宽度分隔符,可以描述为在5个字符前面的地方分割字符串(通过使用\K正面看后面)

    my @mkh = split (/.{5}\K/, $_);
    

    【讨论】:

      猜你喜欢
      • 2014-07-20
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      相关资源
      最近更新 更多