Come posso convertire una stringa in un numero in Perl?


86

Ho una stringa che contiene un valore decimale e ho bisogno di convertire quella stringa in una variabile a virgola mobile. Quindi un esempio della stringa che ho è "5.45" e voglio un equivalente in virgola mobile in modo da poter aggiungere .1 ad esso. Ho cercato in Internet, ma vedo solo come convertire una stringa in un numero intero.


La domanda necessita di ulteriori dettagli. La stringa è composta solo da numeri? Alfanumerico? Ok se gli alfa vengono rimossi? C'è uno scopo specifico per il numero risultante?
JGurtz

Risposte:


90

Non è necessario convertirlo affatto:

% perl -e 'print "5.45" + 0.1;'
5.55

25
5.55 non è un numero intero
OrangeDog

15
@OrangeDog l'OP ha modificato la domanda (alcuni mesi dopo che questa risposta è stata pubblicata) - la domanda originale aveva effettivamente numeri in virgola mobile.
Alnitak

1
che dire dei confronti quando la stringa contiene una virgola?
Ramy

[rabdelaz@Linux_Desktop:~/workspace/akatest_5]$perl -e 'print "nope\n" unless "1,000" > 10;' nope [rabdelaz@Linux_Desktop:~/workspace/akatest_5]$perl -e 'print "nope\n" if "1,000" > 10;'
Ramy

73

Questa è una soluzione semplice:

Esempio 1

my $var1 = "123abc";
print $var1 + 0;

Risultato

123

Esempio 2

my $var2 = "abc123";
print $var2 + 0;

Risultato

0

7
AFAIU questa è l'unica risposta a ciò che è stato chiesto
Cougar

4
Fai attenzione quando aggiungi zero a una stringa. Se la stringa inizia con "inf" o con "nan", il valore non sarà zero. Ad esempio my $ var2 = "info123"; print $ var2 + 0: Il risultato sarà: Inf
Rodrigo De Almeida Siqueira

Stavo facendo un foreach my $i ('00'..'15')e avevo bisogno di rimuovere gli zeri iniziali in alcuni punti. Anche questo 0+casting per un numero ottiene questo.
stevesliva

Apparentemente questo non funziona con le stringhe esadecimali: '0x14C' + 0 risulta in 0 (arrggg)
Allasso

41

Perl è un linguaggio basato sul contesto. Non fa il suo lavoro in base ai dati che gli dai. Invece, capisce come trattare i dati in base agli operatori che usi e al contesto in cui li usi. Se fai numeri un po 'di cose, ottieni numeri:

# numeric addition with strings:
my $sum = '5.45' + '0.01'; # 5.46

Se fai stringhe un po 'di cose, ottieni stringhe:

# string replication with numbers:
my $string = ( 45/2 ) x 4; # "22.522.522.522.5"

Perl per lo più capisce cosa fare ed è per lo più giusto. Un altro modo per dire la stessa cosa è che Perl si preoccupa più dei verbi che dei sostantivi.

Stai cercando di fare qualcosa e non funziona?


Perdona la mia mancanza di conoscenza qui, ma non riesco a capire il tuo secondo esempio. Stai dividendo due numeri, poi moltiplicandoli, come / perché questo si traduce in una stringa?
gideon

4
Non sto moltiplicando i numeri. Il xè l'operatore di replica stringa.
brian d foy

3
Non dovrebbe essere my $string = ( 45/2 ) x 3; # "22.522.522.5"con 45 invece di 44? Altrimenti non capisco da dove vengono gli '.5 nel risultato ...
Vickster

10

Google mi ha portato qui mentre cercavo la stessa domanda posta da phill (ordinamento dei float), quindi ho pensato che sarebbe valsa la pena pubblicare la risposta nonostante il thread fosse un po 'vecchio. Sono nuovo in Perl e mi sto ancora girando la testa, ma l'affermazione di Brian D Foy "Perl si preoccupa più dei verbi che dei sostantivi." sopra colpisce davvero il chiodo sulla testa. Non è necessario convertire le stringhe in float prima di applicare l'ordinamento. Devi dire all'ordinamento di ordinare i valori come numeri e non stringhe. cioè

my @foo = ('1.2', '3.4', '2.1', '4.6');
my @foo_sort = sort {$a <=> $b} @foo;

Vedi http://perldoc.perl.org/functions/sort.html per maggiori dettagli sull'ordinamento


8

Da quanto ho capito, int () non è inteso come una funzione 'cast' per designare il tipo di dati, viene semplicemente (ab) usato qui per definire il contesto come uno aritmetico. Ho (ab) usato (0 + $ val) in passato per assicurarmi che $ val sia trattato come un numero.


sì, int()viene "(ab) usato"; fatto.
Sapphire_Brick

6
$var += 0

probabilmente quello che vuoi. Attenzione, tuttavia, se $ var è una stringa non può essere convertita in numerica, verrà visualizzato l'errore e $ var verrà reimpostato su 0 :

my $var = 'abc123';
print "var = $var\n";
$var += 0;
print "var = $var\n";

registri

var = abc123
Argument "abc123" isn't numeric in addition (+) at test.pl line 7.
var = 0

3

Perl ha solo tre tipi: scalari, array e hash. E anche questa distinzione è discutibile. ;) Il modo in cui ogni variabile viene trattata dipende da cosa ne fai:

% perl -e "print 5.4 . 3.4;"
5.43.4


% perl -e "print '5.4' + '3.4';"
8.8

5
Perl ha molti più tipi di, ma per valori singoli, è solo un singolo valore.
brian d foy

1

Nei confronti fa differenza se uno scalare è un numero di una stringa. E non è sempre decidibile. Posso segnalare un caso in cui perl ha recuperato un float in notazione "scientifica" e ha usato lo stesso poche righe sotto in un confronto:

use strict;
....
next unless $line =~ /and your result is:\s*(.*)/;
my $val = $1;
if ($val < 0.001) {
   print "this is small\n";
}

E qui $valnon è stato interpretato come numerico per esempio "2e-77"recuperato da $line. L'aggiunta di 0 (o 0,0 per i buoni programmatori in C) ha aiutato.


0

Perl è debolmente tipizzato e basato sul contesto. Molti scalari possono essere trattati sia come stringhe che come numeri, a seconda degli operatori utilizzati. $a = 7*6; $b = 7x6; print "$a $b\n";
Ottieni42 777777 .

Tuttavia, c'è una sottile differenza. Quando leggi i dati numerici da un file di testo in una struttura dati e poi li visualizzi con Data::Dumper, noterai che i tuoi numeri sono citati. Perl li tratta internamente come stringhe.
Leggi: $my_hash{$1} = $2 if /(.+)=(.+)\n/;.
Dump:'foo' => '42'

Se si desidera che i numeri non quotate in discarica:
Leggi: $my_hash{$1} = $2+0 if /(.+)=(.+)\n/;.
Dump:'foo' => 42

Dopo che $2+0Perl ha notato che hai trattato $ 2 come un numero, perché hai usato un operatore numerico.

L'ho notato mentre cercavo di confrontare due hash con Data::Dumper.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.