[英]Splitting a String with Perl
当我遇到一个让我感到困惑的引语时,我正在关注如何拆分字符串的本教程 。
关于语境的话
正常使用时,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;
}
我不完全理解你如何在列表中使用拆分。
根据我的理解,在$str
变量上使用split
函数是不受欢迎的? 那么我怎么会用逗号分隔字符串作为分隔符呢?
该段所记录的皱眉行为至少被推迟至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
在标量上下文中调用split
是不太有用的。 它有效地返回分隔符的数量加上一个,并且有更好的方法可以做到这一点。
例如,
my $str = "This,is,data";
my $splitData = split(/,/, $str);
say $splitData;
将在分割后计算子字符串时打印3
。
split
在使用中也回归分裂部scalarf方面@_
,但皱起了眉头,在行为删除,因为它是相当意外的。
将它用作阵列是完美的。
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
作为标量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.