Como posso converter uma string em um número em Perl?


86

Eu tenho uma string que contém um valor decimal e preciso converter essa string em uma variável de ponto flutuante. Portanto, um exemplo da string que tenho é "5,45" e quero um equivalente em ponto flutuante para poder adicionar 0,1 a ele. Eu pesquisei na internet, mas só vejo como converter uma string para um inteiro.


A questão precisa de mais detalhes. A corda é composta apenas de numerais? Alfanumérico? Ok, se os alfas forem removidos? Existe um propósito específico para o número resultante?
JGurtz 01 de

Respostas:


90

Você não precisa convertê-lo de forma alguma:

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

26
5,55 não é um número inteiro
OrangeDog

15
@OrangeDog o OP editou a pergunta (alguns meses depois que esta resposta foi postada) - a pergunta original na verdade continha números de ponto flutuante.
Alnitak

1
que tal comparações quando a string contém uma vírgula?
Ramy de

[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 de

73

Esta é uma solução simples:

Exemplo 1

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

Resultado

123

Exemplo 2

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

Resultado

0

7
AFAIU esta é a única resposta ao que foi perguntado
Cougar

4
Cuidado ao adicionar zero a uma string. Se a string começar com "inf" ou com "nan", o valor não será zero. Por exemplo, meu $ var2 = "info123"; imprimir $ var2 + 0: O resultado será: Inf
Rodrigo De Almeida Siqueira

Eu estava fazendo um foreach my $i ('00'..'15')e precisava remover os zeros à esquerda em alguns lugares. Este 0+elenco para um número também atinge isso.
stevesliva

Aparentemente, isso não funciona com strings hexadecimais: '0x14C' + 0 resulta em 0 (arrggg)
Allasso

41

Perl é uma linguagem baseada em contexto. Ele não faz seu trabalho de acordo com os dados que você fornece. Em vez disso, ele descobre como tratar os dados com base nos operadores que você usa e no contexto em que você os usa. Se você fizer várias coisas com números, obterá números:

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

Se você fizer cadeias de caracteres, você obterá cadeias de caracteres:

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

Perl geralmente descobre o que fazer e está certo. Outra maneira de dizer a mesma coisa é que Perl se preocupa mais com os verbos do que com os substantivos.

Você está tentando fazer algo e não está funcionando?


Perdoe minha falta de conhecimento aqui, mas não entendi bem o seu segundo exemplo. Você está dividindo dois números e, em seguida, multiplicando-os, como / por que isso resulta em uma string?
gideon

4
Não estou multiplicando números. O xé o operador de replicação de string.
brian d foy

3
Não deveria ser my $string = ( 45/2 ) x 3; # "22.522.522.5"com 45 em vez de 44? Caso contrário, não entendo de onde vêm os '.5 no resultado ...
Vickster

10

O Google me conduziu até aqui enquanto pesquisava a mesma pergunta que phill fez (classificando os flutuadores), então achei que valeria a pena postar a resposta, apesar de o tópico ser meio antigo. Eu sou novo no perl e ainda estou pensando nisso, mas a declaração de brian d foy "Perl se preocupa mais com os verbos do que com os substantivos." acima realmente atinge o prego na cabeça. Você não precisa converter as strings em flutuantes antes de aplicar a classificação. Você precisa dizer ao sort para classificar os valores como números e não strings. ie

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

Consulte http://perldoc.perl.org/functions/sort.html para obter mais detalhes sobre classificação


8

Pelo que entendi, int () não se destina a ser uma função de 'conversão' para designar o tipo de dados, está simplesmente sendo (ab) usado aqui para definir o contexto como aritmético. Eu (ab) usei (0 + $ val) no passado para garantir que $ val seja tratado como um número.


sim, int()está sendo "(ab) usado"; Entendi.
Sapphire_Brick

6
$var += 0

provavelmente o que você quer. No entanto, esteja avisado, se $ var is string não puder ser convertido em numérico, você obterá o erro, e $ var será redefinido para 0 :

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

Histórico

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

3

Perl realmente tem apenas três tipos: escalares, matrizes e hashes. E mesmo essa distinção é discutível. ;) A forma como cada variável é tratada depende do que você faz com ela:

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


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

5
Perl tem muito mais tipos do que, mas para valores únicos, é apenas um único valor.
brian d foy

1

Em comparações, faz diferença se um escalar for um número de uma string. E nem sempre é decidível. Posso relatar um caso em que perl recuperou um float em notação "científica" e usou o mesmo algumas linhas abaixo em uma comparação:

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

E aqui $valnão foi interpretado como numérico para, por exemplo, "2e-77"recuperado de $line. Adicionar 0 (ou 0,0 para bons programadores em C) ajudou.


0

Perl é fracamente tipado e baseado em contexto. Muitos escalares podem ser tratados como strings e números, dependendo dos operadores usados. $a = 7*6; $b = 7x6; print "$a $b\n";
Você consegue 42 777777.

Porém, há uma diferença sutil. Quando você lê dados numéricos de um arquivo de texto em uma estrutura de dados e os visualiza com Data::Dumper, você notará que seus números estão entre aspas. Perl os trata internamente como strings.
Leia-se: $my_hash{$1} = $2 if /(.+)=(.+)\n/;.
Despejar:'foo' => '42'

Se você quiser números não cotadas no despejo:
Leia: $my_hash{$1} = $2+0 if /(.+)=(.+)\n/;.
Despejar:'foo' => 42

Depois que $2+0Perl percebe que você tratou $ 2 como um número, porque você usou um operador numérico.

Percebi isso ao tentar comparar dois hashes com Data::Dumper.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.