Comment puis-je convertir une chaîne en nombre en Perl?

86

J'ai une chaîne qui contient une valeur décimale et je dois convertir cette chaîne en une variable à virgule flottante. Donc, un exemple de la chaîne que j'ai est "5.45" et je veux un équivalent en virgule flottante afin que je puisse y ajouter .1. J'ai cherché sur Internet, mais je ne vois que comment convertir une chaîne en entier.

Anton
la source
La question a besoin de plus de détails. La chaîne est-elle uniquement composée de chiffres? Alphanumérique? Ok si les alphas sont dépouillés? Y a-t-il un but spécifique pour le nombre résultant?
JGurtz

Réponses:

90

Vous n'avez pas du tout besoin de le convertir:

% perl -e 'print "5.45" + 0.1;'
5.55
Alnitak
la source
25
5.55 n'est pas un entier
OrangeDog
15
@OrangeDog l'OP a édité la question (quelques mois après la publication de cette réponse) - la question d'origine contenait en fait des nombres à virgule flottante.
Alnitak
1
qu'en est-il des comparaisons lorsque la chaîne contient une virgule?
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

C'est une solution simple:

Exemple 1

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

Résultat

123

Exemple 2

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

Résultat

0
Porquero
la source
7
AFAIU c'est la seule réponse à ce qui a été demandé
Cougar
4
Méfiez-vous lorsque vous ajoutez zéro à une chaîne. Si la chaîne commence par "inf" ou par "nan", la valeur ne sera pas zéro. Par exemple, mon $ var2 = "info123"; print $ var2 + 0: Le résultat sera: Inf
Rodrigo De Almeida Siqueira
Je faisais un foreach my $i ('00'..'15')et j'avais besoin de supprimer les zéros de tête à certains endroits. Ce 0+casting vers un certain nombre y parvient également.
stevesliva
Apparemment, cela ne fonctionne pas avec les chaînes hexadécimales: '0x14C' + 0 donne 0 (arrggg)
Allasso
41

Perl est un langage basé sur le contexte. Il ne fait pas son travail en fonction des données que vous lui donnez. Au lieu de cela, il détermine comment traiter les données en fonction des opérateurs que vous utilisez et du contexte dans lequel vous les utilisez. Si vous faites des nombres, vous obtenez des nombres:

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

Si vous faites des choses comme des chaînes, vous obtenez des chaînes:

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

Perl sait principalement quoi faire et c'est généralement juste. Une autre façon de dire la même chose est que Perl se soucie plus des verbes que des noms.

Essayez-vous de faire quelque chose et cela ne fonctionne pas?

brian d foy
la source
Pardonnez mon manque de connaissances ici, mais je ne comprends pas tout à fait votre deuxième exemple. Vous divisez deux nombres, puis les multipliez, comment / pourquoi cela se traduit-il par une chaîne?
gideon
4
Je ne multiplie pas les nombres. Le xest l'opérateur de réplication de chaîne.
brian d foy
3
Ne devrait-il pas être my $string = ( 45/2 ) x 3; # "22.522.522.5"avec 45 au lieu de 44? Sinon, je ne comprends pas d'où viennent les '.5 dans le résultat ...
Vickster
10

Google m'a conduit ici en cherchant sur la même question posée par phill (tri des flotteurs), alors j'ai pensé qu'il vaudrait la peine de poster la réponse malgré le fil de discussion étant un peu vieux. Je suis nouveau en perl et j'ai toujours la tête autour de lui, mais la déclaration de brian d foy "Perl se soucie plus des verbes que des noms." ci-dessus frappe vraiment le clou sur la tête. Vous n'avez pas besoin de convertir les chaînes en flottants avant d'appliquer le tri. Vous devez indiquer au tri pour trier les valeurs sous forme de nombres et non de chaînes. c'est à dire

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

Voir http://perldoc.perl.org/functions/sort.html pour plus de détails sur le tri

Norme
la source
8

Si je comprends bien, int () n'est pas destiné à être une fonction `` cast '' pour désigner le type de données, il est simplement utilisé ici pour définir le contexte comme un contexte arithmétique. J'ai (ab) utilisé (0 + $ val) dans le passé pour m'assurer que $ val est traité comme un nombre.

mccutchm
la source
oui, int()est "(ab) utilisé"; je l'ai.
Sapphire_Brick
6
$var += 0

probablement ce que vous voulez. Soyez averti cependant, si $ var est une chaîne ne peut pas être convertie en numérique, vous obtiendrez l'erreur et $ var sera réinitialisé à 0 :

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

journaux

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

Perl n'a en réalité que trois types: scalaires, tableaux et hachages. Et même cette distinction est discutable. ;) La façon dont chaque variable est traitée dépend de ce que vous en faites:

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


% perl -e "print '5.4' + '3.4';"
8.8
Rini
la source
5
Perl a beaucoup plus de types que, mais pour des valeurs uniques, il ne s'agit que d'une seule valeur.
brian d foy
1

Dans les comparaisons, cela fait une différence si un scalaire est un nombre d'une chaîne. Et ce n'est pas toujours décidable. Je peux rapporter un cas où perl a récupéré un flottant en notation "scientifique" et l'a utilisé quelques lignes ci-dessous dans une comparaison:

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

Et ici $valn'a pas été interprété comme numérique pour, par exemple, "2e-77"récupéré à partir de $line. L'ajout de 0 (ou 0,0 pour les bons programmeurs en C) a aidé.

Steffen Moeller
la source
0

Perl est faiblement typé et basé sur le contexte. De nombreux scalaires peuvent être traités à la fois comme des chaînes et des nombres, selon les opérateurs que vous utilisez. $a = 7*6; $b = 7x6; print "$a $b\n";
Vous obtenez 42 777777.

Il y a cependant une différence subtile. Lorsque vous lisez des données numériques à partir d'un fichier texte dans une structure de données, puis que vous les affichez avec Data::Dumper, vous remarquerez que vos nombres sont indiqués. Perl les traite en interne comme des chaînes.
Lire: $my_hash{$1} = $2 if /(.+)=(.+)\n/;.
Déverser:'foo' => '42'

Si vous souhaitez que les numéros non cotés dans la décharge:
Lire: $my_hash{$1} = $2+0 if /(.+)=(.+)\n/;.
Déverser:'foo' => 42

Après que $2+0Perl a remarqué que vous avez traité $ 2 comme un nombre, parce que vous avez utilisé un opérateur numérique.

J'ai remarqué cela en essayant de comparer deux hachages avec Data::Dumper.

SzG
la source