my $ str =“1:2:3:4:5”; 我的($ a,$ b)=拆分(':',$ str,2);
在上面的代码中,我使用limit作为2,因此$ a将包含1,其余元素将在$ b中。 像这样我希望最后一个元素应该在一个变量中,而最后一个元素之前的元素应该在另一个变量中。
示例
$str = "1:2:3:4:5" ;
# $a should have "1:2:3:4" and $b should have "5"
$str = "2:3:4:5:3:2:5:5:3:2"
# $a should have "2:3:4:5:3:2:5:5:3" and $b should have "2"
答案 0 :(得分:18)
split(/:([^:]+)$/, $str)
答案 1 :(得分:8)
你也可以使用rindex()
例如
my $str="1:2:3:4:5";
$i=rindex($str,":");
$a=substr($str,0,$i);
$b=substr($str,$i+1);
print "\$a:$a, \$b: $b\n";
输出
$ perl perl.pl
$a:1:2:3:4, $b: 5
答案 2 :(得分:8)
您可以使用匹配,而不是分割:
my ($a,$b) = $str =~ /(.*):(.*)/;
答案 3 :(得分:3)
我知道,这个问题是4岁。但我发现YOU的答案非常有趣,因为我不知道split
可以这样做。所以我想用perldoc split的摘录来扩展它,以解释这种行为,为了新读者的利益。 : - )
my $str = "1:2:3:4:5";
my ($a, $b) = split /:([^:]+)$/, $str;
# Capturing everything after ':' that is not ':' and until the end of the string
# Now $a = '1:2:3:4' and $b = '5';
来自Perldoc:
如果PATTERN包含捕获组,则对于每个分隔符,将为组捕获的每个子字符串生成一个附加字段(按照指定组的顺序,根据后向引用);如果任何组不匹配,则它捕获undef值而不是子字符串。此外,请注意,只要存在分隔符(即,每当发生分割时)就会产生任何此类附加字段,并且此类附加字段不计入LIMIT。考虑在列表上下文中计算的以下表达式(每个返回的列表在关联的注释中提供):
split(/-|,/, "1-10,20", 3)
# ('1', '10', '20')
split(/(-|,)/, "1-10,20", 3)
# ('1', '-', '10', ',', '20')
split(/-|(,)/, "1-10,20", 3)
# ('1', undef, '10', ',', '20')
split(/(-)|,/, "1-10,20", 3)
# ('1', '-', '10', undef, '20')
split(/(-)|(,)/, "1-10,20", 3)
# ('1', '-', undef, '10', undef, ',', '20')
答案 4 :(得分:2)
您可以使用拆分和反向执行此操作,如下所示:
my $str="1:2:3:4:5";
my ($a,$b)=split(':',reverse($str),2); # reverse and split.
$a = reverse($a); # reverse each piece.
$b = reverse($b);
($a,$b) = ($b,$a); # swap a and b
现在$a
将是1:2:3:4
,$b
将是5
。
更简单,更简洁的方法是使用正则表达式,正如马克在他的答案中所做的那样。
答案 5 :(得分:-1)
我对这个问题有点迟了,但我总结了一个更通用的解决方案:
# Similar to split() except pattern is applied backwards from the end of the string
# The only exception is that the pattern must be a precompiled regex (i.e. qr/pattern/)
# Example:
# rsplit(qr/:/, 'John:Smith:123:ABC', 3) => ('John:Smith', '123', 'ABC')
sub rsplit {
my $pattern = shift(@_); # Precompiled regex pattern (i.e. qr/pattern/)
my $expr = shift(@_); # String to split
my $limit = shift(@_); # Number of chunks to split into
# 1) Reverse the input string
# 2) split() it
# 3) Reverse split()'s result array element order
# 4) Reverse each string within the result array
map { scalar reverse($_) } reverse split(/$pattern/, scalar reverse($expr), $limit);
}
它接受类似于split()
的参数,除了拆分以相反的顺序完成。如果您需要指定数量的结果元素,它还接受限制子句。
注意:此子例程需要precompiled regex作为第一个参数。
Perl的split
是内置的,会正确解释/pat/
,但尝试将/pat/
传递给子例程将被视为sub($_ =~ /pat/)
。
这个子程序不是防弹的!它适用于简单的分隔符,但更复杂的模式可能会导致问题。模式本身不能反转,只能反映它匹配的表达式。
示例:
rsplit(qr/:/, 'One:Two:Three', 2); # => ('One:Two', 'Three')
rsplit(qr/:+/, 'One:Two::Three:::Four', 3); # => ('One:Two', 'Three', 'Four')
# Discards leading blank elements just like split() discards trailing blanks
rsplit(qr/:/, ':::foo:bar:baz'); # => ('foo', 'bar', 'baz')