【问题标题】:Split a string into array in Perl在 Perl 中将字符串拆分为数组
【发布时间】:2013-05-28 03:55:42
【问题描述】:
my $line = "file1.gz file2.gz file3.gz";
my @abc = split('', $line);
print "@abc\n";

预期输出:

file1.gz
file2.gz
file3.gz

我希望输出为$abc[0] 中的file1.gz$abc[1] 中的file2.gz$abc[2] 中的file3.gz。如何拆分$line

【问题讨论】:

  • 好吧,没有编程语言可以读懂你的想法。 split '' 拆分为单个字符。如果你所有的文件名都以file... 开头,那么split /(?=file)/ 可以,但是没有通用的解决方案
  • @aragaer 您的评论实际上是错误的。 split 将参数作为模式、字符串、限制。你的订单是错误的。 print "@abc\n" 可以正常工作,前提是 $" eq "\n"$" 通常是一个空格)。

标签: arrays string perl split


【解决方案1】:

用空格分割字符串很简单:

print $_, "\n" for split ' ', 'file1.gz file1.gz file3.gz';

这实际上是split 的一种特殊形式(因为这个函数通常采用模式而不是字符串):

作为另一种特殊情况,split 模拟了 命令行工具 awkPATTERN 被省略或为文字时 由单个空格字符组成的字符串(例如' '"\x20")。在这种情况下,EXPR 中的任何前导空格都是 在拆分发生之前删除,PATTERN 被视为 如果是/\s+/;特别是,这意味着任何连续的 空格(不仅仅是单个空格字符)用作分隔符。


这是原始问题的答案(使用没有任何空格的简单字符串):

也许你想在.gz 分机上拆分:

my $line = "file1.gzfile1.gzfile3.gz";
my @abc = split /(?<=\.gz)/, $line;
print $_, "\n" for @abc;

这里我使用(?&lt;=...)构造,即look-behind assertion,基本上是在.gz子字符串前面的行中的每个点进行拆分。

如果您使用固定的扩展集,您可以扩展该模式以将它们全部包含在内:

my $line = "file1.gzfile2.txtfile2.gzfile3.xls";
my @exts = ('txt', 'xls', 'gz');
my $patt = join '|', map { '(?<=\.' . $_ . ')' } @exts;
my @abc = split /$patt/, $line;
print $_, "\n" for @abc;

【讨论】:

  • 问题已更改为包含空格
  • @user2384801 添加了解释和链接。
【解决方案2】:

拥有$line 现在,您可以根据至少一个空格分隔符简单地拆分字符串

my @answer = split(' ', $line); # creates an @answer array

然后

print("@answer\n");               # print array on one line

print("$_\n") for (@answer);      # print each element on one line

我更喜欢将() 用于splitprintfor

【讨论】:

  • 您应该知道默认的' ' 拆分可能是您想要的,而不是/\s+/。它们完全一样,除了默认在拆分前去除前导空格。
  • @TLP 非常感谢 - 一直使用 /\s+/ 忽略默认的 ' '。我仍然发现/\s+/ 更容易理解,因为它显示的内容......但我猜' ' 很容易记住,完全符合人们的要求(通常没有人关心将 0 字符串作为第一个元素),并且是当然优化后无需昂贵的正则表达式使用。答案已更新。
【解决方案3】:

只需使用 /\s+/ 反对 '' 作为分隔符。在这种情况下,所有“额外”的空白都被删除了。通常需要这种特殊行为。所以,在你的情况下,它将是:

my $line = "file1.gz file1.gz file3.gz";
my @abc = split(/\s+/, $line);

【讨论】:

    【解决方案4】:

    我发现这个很简单!

    my $line = "file1.gz file2.gz file3.gz";
    
    my @abc =  ($line =~ /(\w+[.]\w+)/g);
    
    print $abc[0],"\n";
    print $abc[1],"\n";
    print $abc[2],"\n";
    

    输出:

    file1.gz 
    file2.gz 
    file3.gz
    

    查看本教程以了解更多关于 Perl regular expression 的信息并向下滚动到更多匹配部分。

    【讨论】:

      【解决方案5】:

      您的问题已有多个答案,但我想在此处添加另一个小问题,这可能有助于添加一些内容。

      要查看 Perl 中的数据结构,您可以使用 Data::Dumper。要打印字符串,您可以使用say,它会在每次调用后添加一个换行符"\n",而不是显式添加。

      我通常使用匹配空白字符的\s。如果您添加+,它将匹配一个或多个空白字符。你可以在这里阅读更多关于它的信息perlre

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      use Data::Dumper;
      
      use feature 'say';
      
      my $line = "file1.gz file2.gz file3.gz";
      my @abc  = split /\s+/, $line;
      
      print Dumper \@abc;
      say for @abc;
      

      【讨论】:

      • 人们是否有理由降级这个答案?根据Perl::doc 的官方文档:“在这种情况下,EXPR 中的任何前导空格在拆分发生之前都会被删除,而 PATTERN 则被视为 /\s+/ ;特别是,这意味着任何连续的空格(不仅仅是单个空格字符)都用作分隔符。"
      猜你喜欢
      • 1970-01-01
      • 2016-05-21
      • 1970-01-01
      • 2012-10-13
      • 2011-08-28
      • 2016-04-01
      • 2012-02-22
      相关资源
      最近更新 更多