2012-03-19 17 views
5

Vorrei rimuovere tutto il . da una stringa tranne dall'ultima.Come rimuovere tutto. dalla stringa eccetto l'ultima?

Può essere fatto in JavaScript in questo modo

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

ma quando provare la stessa in Perl

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

ottengo

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

Domanda

Qualcuno può capire come farlo in Perl?

risposta

8

vorrei usare un espressione regolare con positiva look-ahead in perl per l'attività:

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

Risultato:

123.4 

MODIFICA per aggiungere una correzione alla soluzione utilizzando 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

uso eccessivo di 'printf' lì quando' print' sarà sufficiente. – TLP

+1

È il modo per capire la tua visione positiva in questo modo ?: il contenuto in '()' viene eseguito per primo, e poiché '. *' È avido, troverà l'ultimo '.' e tutti i' .' ' il regex incontra sul suo modo viene sostituito con nulla? –

+2

@SandraSchlichting No, la regex troverà un periodo letterale, e l'anteprima confermerà che c'è almeno un periodo letterale da qualche parte più avanti. Quando l'asserzione fallisce, avrai trovato l'ultimo periodo. – TLP

4

Prima di tutto, la fuga il punto di istruzioni divisa: my @parts = split /\./, $s;

4

tuo split sta usando una regex /./, nel qual caso . è considerato il carattere jolly. Se si desidera dividere su un periodo letterale, è necessario sfuggire:

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

splice prende argomenti array o ESPR, SCOSTAMENTO, LUNGHEZZA, LISTA (v5.14 perl). Se LENGTH è 0, nulla viene rimosso e quindi non viene restituito nulla.

Il tuo codice è in contraddizione con quello che dici di voler provare, quindi non sono abbastanza sicuro di cosa stia provando a fare, ma supponendo che tu voglia rimuovere tutti i periodi tranne l'ultimo, vorrei aspetto che tu faresti qualcosa di simile:

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

O forse manipolare la scissione

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

quindi, fondamentalmente, scoprire quanti campi la stringa sarà diviso in, sottrarre uno, quindi eseguire una nuova spaccatura e imposta il LIMIT a questo.

+0

Il primo non gestisce '1234', e nessuno dei due gestisce' 1.2.3.4', se è importante. – ikegami

3

in caso di dubbio, 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 

dubito che si desidera utilizzare offset negativi, penso che si desidera utilizzare di offset 0 e dimensioni dell'array meno uno (anche conosciuto come l'ultimo indice)

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

Ooops.$ # ARGV è l'ultimo indice, non $ # ARGV -1, quindi

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

ma se si vuole ancora un po 'di aritmetica è possibile utilizzare @ARGV, causa nel contesto scalare propria la dimensione della matrice

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

Vantaggio laterale dell'utilizzo di offset non negativi con giunzione? Non muore quando array è vuoto

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

Questo sembra più simile a quello che stavi cercando di fare in Perl

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

Non gestisce '1234' o' 1.2.3.4', se è importante. – ikegami

0

vi siete persi la '.' il vostro splice chiamata. Ecco come dovrebbe apparire

use strict; 
use warnings; 

my $s = '1.2.3.4'; 

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

Non gestisce '1234' o' 1.2.3.4', se è importante. – ikegami

0

Il primo argomento di split è un'espressione regolare. Nelle espressioni regolari, "." significa "corrisponde a qualsiasi carattere" (con/s) o "corrisponde a qualsiasi carattere tranne LF" (senza/s). È necessario sfuggire per corrispondere a un letterale ".".

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

una sostituzione potrebbe farlo pure:

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