2012-03-19 32 views
5

Tôi muốn xóa tất cả . khỏi chuỗi trừ chuỗi cuối cùng.Cách xóa tất cả. từ chuỗi ngoại trừ chuỗi cuối cùng?

Nó có thể được thực hiện trong JavaScript như vậy

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

nhưng khi cố gắng như nhau trong Perl

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

tôi nhận được

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

Câu hỏi

Bất cứ ai có thể tìm ra cách để làm điều này trong Perl?

Trả lời

8

Tôi sẽ sử dụng một regexp với dương nhìn về phía trước trong perl cho nhiệm vụ:

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

Kết quả:

123.4 

EDIT để thêm bản sửa lỗi vào giải pháp của bạn bằng cách sử dụng 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"; 
+2

Sử dụng quá nhiều của 'printf' có khi' print' sẽ đủ. – TLP

+1

Có phải cách để hiểu cái nhìn tích cực của bạn như thế này không ?: nội dung trong '()' được thực hiện trước tiên, và bởi vì '. *' Là tham lam nó sẽ tìm thấy '.' cuối cùng và tất cả' .' Regex gặp trên đường của nó được thay thế bằng không có gì? –

+2

@SandraSchlichting Không, regex sẽ tìm thấy một khoảng thời gian, và nhìn về phía trước sẽ khẳng định rằng có ít nhất một khoảng thời gian ở đâu đó phía trước. Khi xác nhận không thành công, bạn sẽ tìm thấy khoảng thời gian cuối cùng. – TLP

4

Trước hết, thoát khỏi dấu chấm trong hướng dẫn phân chia: my @parts = split /\./, $s;

4

bạn split đang sử dụng một regex /./, trong trường hợp . được coi là nhân vật thẻ hoang dã. Nếu bạn muốn chia vào một giai đoạn đen, bạn cần phải thoát khỏi nó:

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

splice lấy đối số ARRAY hoặc EXPR, OFFSET, LENGTH, DANH (perl v5.14). Nếu LENGTH bằng 0, không có gì bị xóa và do đó không có gì được trả lại.

Mã của bạn mâu thuẫn với những gì bạn nói, vì vậy tôi không chắc bạn thực sự muốn làm gì, nhưng giả sử bạn muốn xóa tất cả các khoảng trừ lần cuối, tôi sẽ mong đợi bạn muốn làm điều gì đó như:

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

Hoặc có lẽ thao tác chia

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

Vì vậy, về cơ bản, tìm hiểu cách thức nhiều lĩnh vực chuỗi của bạn sẽ được chia thành, trừ một, sau đó thực hiện một sự chia rẽ mới và đặt LIMIT thành cái đó.

+0

Đầu tiên không xử lý '1234' và không xử lý' 1.2.3.4.', nếu nó quan trọng. – ikegami

3

khi nghi ngờ, 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 

tôi nghi ngờ bạn muốn sử dụng offsets tiêu cực, tôi nghĩ rằng bạn muốn sử dụng offset 0 và kích thước của mảng trừ một (hay còn gọi là chỉ số cuối cùng)

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

Rất tiếc.$ # Argv là chỉ số cuối cùng, chứ không phải $ # argv -1, vì vậy

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

nhưng nếu bạn vẫn muốn có một số số học bạn có thể sử dụng @ARGV, nguyên nhân trong bối cảnh vô hướng của nó kích thước của mảng

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

Lợi ích phụ của việc sử dụng bù trừ không âm với mối nối? Nó không chết khi mảng trống

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

này trông giống như những gì bạn đang cố gắng để làm trong Perl

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

Không xử lý '1234' hoặc' 1.2.3.4.', nếu nó quan trọng. – ikegami

0

Bạn bỏ lỡ '.' tắt splice cuộc gọi của bạn. Dưới đây là cách hiển thị hình ảnh

use strict; 
use warnings; 

my $s = '1.2.3.4'; 

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

Không xử lý '1234' hoặc' 1.2.3.4.', nếu nó quan trọng. – ikegami

0

Đối số đầu tiên là split là cụm từ thông dụng. Trong cụm từ thông dụng, "." có nghĩa là "khớp với bất kỳ ký tự nào" (có/s) hoặc "khớp với bất kỳ ký tự nào trừ LF" (không có/s). Bạn cần phải thoát khỏi nó để phù hợp với một chữ ".".

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

Một thay thể làm điều đó cũng như:

$s =~ s/\.(?=.*\.)//sg; 
Các vấn đề liên quan