用Perl拆分字符串

时间:2017-05-25 13:59:47

标签: string perl split

当我遇到一个让我困惑的引语时,我跟着这个tutorial关于如何分割字符串。

  

有关上下文的文字

     

正常使用时,split在列表上下文中使用。它也可能是   在标量上下文中使用,尽管它在标量上下文中使用   弃用。在标量上下文中,split返回字段数   找到了,并拆分成@_数组。很容易理解为什么会这样   不可取,因此,为什么在标量上下文中使用split是   不高兴。

我有以下与我合作过的脚本:

#!/usr/bin/perl
use strict;
use warnings;
use v5.24;

doWork();

sub doWork {
    my $str = "This,is,data";
    my @splitData = split(/,/, $str);
    say $splitData[1];
    return; 
} 

我不完全明白如何在列表中使用拆分。

根据我的理解,在split变量上使用$str函数是不受欢迎的?那么我怎么会用逗号分隔字符串作为分隔符呢?

2 个答案:

答案 0 :(得分:2)

该段所记录的皱眉行为至少被推迟至5.8.8(11年前),并于5.12(7年前)从Perl中删除。

段落文件

my $n = split(...);

相当于

my $n = do { @_ = split(...); @_ };            # <5.12

@_的分配是意外的。这种行为称为“远距离令人惊讶的行为”,它可能导致代码故障。因此,在5.12之前,在标量上下文中使用split是不受欢迎的。但是,从5.12开始,

my $n = split(...);

相当于

my $n = do { my @anon = split(...); @anon };   # ≥5.12

已删除令人惊讶的行为,因为您引用的段落中所述的原因,在标量上下文中使用split不再感到不满。

它应该仍然可以避免,不仅仅是为了向后兼容,而是因为有更好的方法来计算子串的数量。我会使用以下内容:

my $n = 1 + tr/,//;    # Faster than: my $n = split(/,/, $_, -1);

您在列表上下文中使用split,因此无论您使用何种版本的Perl,它都不会行使皱眉的行为。换句话说,您的使用情况很好。

除非你试图处理CSV数据,否则没关系。在这种情况下,您应该使用Text::CSV_XS

use Text::CSV_XS qw( );

my $csv = Text::CSV_XS->new({ auto_diag => 2, binary => 1 });

while (my $row = $csv->getline($fh)) { ... }   # Parsing CSV

for (...) { $csv->say($fh, $row); }            # Generating CSV

答案 1 :(得分:1)

在标量上下文中调用split并不是很有用。它有效地返回了分隔符的数量加上一个,并且有更好的方法可以做到这一点。

例如,

my $str = "This,is,data";
my $splitData = split(/,/, $str);
say $splitData;

将打印3,因为它会在拆分后计算子字符串。

scalarf上下文中的

split过去也会返回@_中的分割部分,但这种皱眉的行为被删除了,因为它很意外。

将它用作数组是完美的。

my $str = "This,is,data";

以上行是单个字符串。

my @splitData = split(/,/, $str);

您现在将$str拆分为数组或值列表。所以你现在正在和@splitData坐在一起,这实际上是:

"This" "is" "string"

因此,您可以全部使用它们,say @splitData或将它们中的每一个用作我们从未使用的标量@splitData[1],因为将它写为$splitData[1]

教程说得很好。在字符串上使用split来创建子字符串列表。

然后,您可以显然自动在循环中分配每个列表值,而无需打印每个列表值。

my $str = "This,is,data";
my @splitData = split(/,/, $str);
foreach $value(@splitData) {
               say "$value\n"
 }

这基本上会将$splitData[0], $splitData[1]等重新分配给$value作为标量。