Perl 如何删除所有。除了最后一个,从字符串开始?

Perl 如何删除所有。除了最后一个,从字符串开始?,perl,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; 我明白了 问题 有人知道如何在Perl中实现这一点吗?首先,在split指令中转

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

可以像这样用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;
我明白了

问题


有人知道如何在Perl中实现这一点吗?

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

我将在
perl
中使用具有积极前瞻性的regexp来完成任务:

perl -pe 's/\.(?=.*\.)//g' <<<"1.2.3.4"
编辑使用
拆分
向解决方案添加修复程序:

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";

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

... split /\./, $s;
splice
接受参数数组或表达式、偏移量、长度、列表(perl v5.14)。如果长度为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;

因此,基本上,找出您的字符串将拆分为多少个字段,减去一个字段,然后执行新的拆分并将限制设置为该字段。

如果有疑问,请使用诊断

$ 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
我怀疑您是否希望使用负偏移量,我认为您希望使用偏移量0和数组大小减1(也称为最后一个索引)

哎呀$#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 "

这看起来更像是您在Perl中尝试执行的操作

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

您错过了
”。
取消了
拼接
呼叫。下面是它的外观

use strict;
use warnings;

my $s = '1.2.3.4';

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

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

替换也可以做到这一点:

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

print
时,在那里过度使用
printf
就足够了。理解你的积极展望的方法是这样的吗?:首先执行
()
中的内容,而且因为
*
是贪婪的,它会找到最后一个
,并且正则表达式在途中遇到的所有
都会被替换为空?@SandraSchlichting No,正则表达式会找到一个文字周期,而前瞻会断言前面至少有一个文字周期。当断言失败时,您将找到最后一个句点。@TLP:谢谢TLP的解释+1拆分解决方案不处理
1234
1.2.3.4.
,如果有问题。不处理
1234
1.2.3.4.
,如果有问题。如果有问题,不处理
1234
1.2.3.4.
。第一个解决方案不处理
1234
,如果有问题,也不处理
1.2.3.4.
my @parts = split /\./, $s;
$s = join('', splice(@parts, 0, -1)) . '.' . $parts[-1];
use strict;
use warnings;

my $s = '1.2.3.4';

my @parts = split /\./, $s;
splice @parts, -1, 0, '.';
$s = join "", @parts;
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;