如何删除所有。从字符串除了最后?

时间:2012-03-19 13:54:44

标签: perl

我想从字符串中删除除最后一个字符串之外的所有.

可以在JavaScript中完成

var s='1.2.3.4';
s=s.split('.');
s.splice(s.length-1,0,'.');
s.join('');

但在Perl中尝试相同时

my @parts = split /./, $s;
my @a = splice @parts, $#parts-1,0;
$s = join "", @a;

我得到了

Modification of non-creatable array value attempted, subscript -2 at ./test.pl line 15.

问题

任何人都可以弄清楚如何在Perl中执行此操作吗?

7 个答案:

答案 0 :(得分:9)

我会在perl中使用正面预测的正则表达式来完成任务:

perl -pe 's/\.(?=.*\.)//g' <<<"1.2.3.4"

结果:

123.4

编辑使用split为您的解决方案添加修补程序:

use warnings;
use strict;

my $s = '1.2.3.4';
my @parts = split /\./, $s; 
$s = join( "", @parts[0 .. $#parts-1] ) . '.' . $parts[$#parts];
printf "$s\n";

答案 1 :(得分:4)

首先,在拆分指令中转义点:my @parts = split /\./, $s;

答案 2 :(得分:4)

您的split正在使用正则表达式/./,在这种情况下,.被视为通配符。如果要分割文字句点,则需要将其转义:

... split /\./, $s;

splice使用参数ARRAY或EXPR,OFFSET,LENGTH,LIST(perl v5.14)。如果LENGTH为0,则不会删除任何内容,因此不会返回任何内容。

你的代码与你所说的你想做的事情是矛盾的,所以我不太确定你真正要做的是什么,但是假设你要删除除了最后一个以外的所有时期,我会期待你会做类似的事情:

my @parts = split /\./, $s;
my $end   = pop @parts;
$s        = join "", @parts, ".$end";

或者也许操纵分裂

my @parts = split /\./, $s;
my $limit = @parts - 1;  # the field count for split
$s        = join "", split /\./, $s, $limit;

基本上,找出你的字符串将分成多少个字段,减去一个,然后执行一个新的分割并将LIMIT设置为。

答案 3 :(得分:3)

如有疑问,use diagnostics;

$ perl -Mdiagnostics -le " splice @ARGV, -1 ,0 "
Modification of non-creatable array value attempted, subscript -1 at -e line 1 (#1)
    (F) You tried to make an array value spring into existence, and the
    subscript was probably negative, even counting from end of the array
    backwards.

Uncaught exception from user code:
        Modification of non-creatable array value attempted, subscript -1 at -e line 1.
 at -e line 1.

$ perl -Mdiagnostics -le " splice @ARGV, -1 ,0 " argv now not empty

我怀疑你想使用负偏移,我想你想使用数组减去1的偏移0和尺寸(也称为最后一个索引)

$ perl -le " print for splice @ARGV, 0, $#ARGV-1 " a b c
a

糟糕! $#ARGV是最后一个索引,而不是$#ARGV -1,所以

$ perl -le " print for splice @ARGV, 0, $#ARGV " a b c
a
b

但是如果你仍然需要一些算法,你可以使用@ARGV,在标量上下文中导致它的数组大小

$ perl -le " print for splice @ARGV, 0, @ARGV-1 " a b c
a
b

使用非负偏移和拼接的副作用?当数组为空时它不会死亡

$ perl -le " print for splice @ARGV, 0, 10 "

答案 4 :(得分:1)

这看起来更像你在Perl中尝试做的事情

my @parts = split /\./, $s;
$s = join('', splice(@parts, 0, -1)) . '.' . $parts[-1];

答案 5 :(得分:0)

您错过了'.'来电splice。这是它应该看起来的样子

use strict;
use warnings;

my $s = '1.2.3.4';

my @parts = split /\./, $s;
splice @parts, -1, 0, '.';
$s = join "", @parts;

答案 6 :(得分:0)

split的第一个参数是正则表达式。在正则表达式中,“.”表示“匹配任何字符”(使用/ s)或“匹配除LF之外的任何字符”(不带/ s)。您需要将其转义为与文字“.”匹配。

my @parts = split(/\./, $s, -1);            # "-1" to handle "1.2.3.4."
splice(@parts, -1, 0, '.') if @parts > 2;   # "if" to handle "1234"
$s = join('', @parts);

替换也可以这样做:

$s =~ s/\.(?=.*\.)//sg;