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.


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

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

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?


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


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.


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

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

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é.


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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.