Wie kann ich eine Zeichenfolge in Perl in eine Zahl konvertieren?

86

Ich habe eine Zeichenfolge, die einen Dezimalwert enthält, und ich muss diese Zeichenfolge in eine Gleitkommavariable konvertieren. Ein Beispiel für die Zeichenfolge, die ich habe, ist "5.45", und ich möchte ein Gleitkommaäquivalent, damit ich .1 hinzufügen kann. Ich habe im Internet gesucht, aber ich sehe nur, wie man eine Zeichenfolge in eine Ganzzahl konvertiert.

Anton
quelle
Die Frage bedarf weiterer Einzelheiten. Besteht die Zeichenfolge nur aus Ziffern? Alphanumerisch? Ok, wenn Alphas entfernt werden? Gibt es einen bestimmten Zweck für die resultierende Anzahl?
JGurtz

Antworten:

90

Sie müssen es überhaupt nicht konvertieren:

% perl -e 'print "5.45" + 0.1;'
5.55
Alnitak
quelle
25
5.55 ist keine ganze Zahl
OrangeDog
15
@OrangeDog das OP hat die Frage bearbeitet (einige Monate nachdem diese Antwort veröffentlicht wurde) - die ursprüngliche Frage enthielt tatsächlich Gleitkommazahlen.
Alnitak
1
Was ist mit Vergleichen, wenn die Zeichenfolge ein Komma enthält?
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

Dies ist eine einfache Lösung:

Beispiel 1

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

Ergebnis

123

Beispiel 2

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

Ergebnis

0
porquero
quelle
7
AFAIU Dies ist die einzige Antwort auf die Frage
Cougar
4
Vorsicht beim Hinzufügen von Null zu einer Zeichenfolge. Wenn die Zeichenfolge mit "inf" oder "nan" beginnt, ist der Wert nicht Null. ZB mein $ var2 = "info123"; print $ var2 + 0: Ergebnis ist: Inf
Rodrigo De Almeida Siqueira
Ich habe a gemacht foreach my $i ('00'..'15')und musste an einigen Stellen die führenden Nullen entfernen. Dieses 0+Casting zu einer Zahl erreicht auch das.
stevesliva
41

Perl ist eine kontextbasierte Sprache. Es macht seine Arbeit nicht gemäß den Daten, die Sie ihm geben. Stattdessen wird anhand der von Ihnen verwendeten Operatoren und des Kontexts, in dem Sie sie verwenden, herausgefunden, wie die Daten behandelt werden. Wenn Sie Zahlen machen, erhalten Sie Zahlen:

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

Wenn Sie Strings machen, erhalten Sie Strings:

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

Perl findet meistens heraus, was zu tun ist und es ist meistens richtig. Eine andere Art, dasselbe zu sagen, ist, dass Perl sich mehr um die Verben kümmert als um die Substantive.

Versuchen Sie etwas zu tun und es funktioniert nicht?

brian d foy
quelle
Verzeihen Sie meinen Mangel an Wissen hier, aber ich verstehe Ihr zweites Beispiel nicht ganz. Sie teilen zwei Zahlen und multiplizieren sie dann. Wie / warum führt dies zu einer Zeichenfolge?
Gideon
4
Ich multipliziere keine Zahlen. Das xist der String-Replikationsoperator.
Brian D Foy
3
Sollte es nicht my $string = ( 45/2 ) x 3; # "22.522.522.5"mit 45 statt 44 sein? Sonst verstehe ich nicht, woher die .5 im Ergebnis kommen ...
Vickster
10

Google hat mich hierher geführt, während ich nach der gleichen Frage gesucht habe, die Phill gestellt hat (Sortier-Floats), also dachte ich, es würde sich lohnen, die Antwort zu veröffentlichen, obwohl der Thread etwas alt ist. Ich bin neu in Perl und habe immer noch meinen Kopf darum gewickelt, aber Brian D Foys Aussage "Perl kümmert sich mehr um die Verben als um die Substantive." oben trifft wirklich den Nagel auf den Kopf. Sie müssen die Zeichenfolgen nicht in Floats konvertieren, bevor Sie die Sortierung anwenden. Sie müssen der Sortierung mitteilen, dass die Werte als Zahlen und nicht als Zeichenfolgen sortiert werden sollen. dh

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

Weitere Informationen zum Sortieren finden Sie unter http://perldoc.perl.org/functions/sort.html

Norm
quelle
8

Soweit ich weiß, ist int () nicht als 'cast'-Funktion zur Bezeichnung des Datentyps gedacht, sondern wird hier einfach (ab) verwendet, um den Kontext als arithmetisch zu definieren. Ich habe (ab) in der Vergangenheit (0 + $ val) verwendet, um sicherzustellen, dass $ val als Zahl behandelt wird.

mccutchm
quelle
ja, int()wird "(ab) verwendet"; Ich habs.
Sapphire_Brick
6
$var += 0

wahrscheinlich was du willst. Seien Sie jedoch gewarnt, wenn $ var is string nicht in numerisch konvertiert werden konnte, wird der Fehler angezeigt und $ var wird auf 0 zurückgesetzt :

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

Protokolle

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

Perl hat wirklich nur drei Typen: Skalare, Arrays und Hashes. Und selbst diese Unterscheidung ist fraglich. ;) Wie jede Variable behandelt wird, hängt davon ab, was Sie damit machen:

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


% perl -e "print '5.4' + '3.4';"
8.8
Rini
quelle
5
Perl hat viel mehr Typen als, aber für einzelne Werte ist es nur ein einzelner Wert.
Brian D Foy
1

Bei Vergleichen macht es einen Unterschied, ob ein Skalar eine Zahl einer Zeichenfolge ist. Und es ist nicht immer entscheidbar. Ich kann einen Fall melden, in dem Perl einen Float in "wissenschaftlicher" Notation abgerufen und diesen ein paar Zeilen weiter unten in einem Vergleich verwendet hat:

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

Und hier $valwurde nicht als numerisch interpretiert, zB von "2e-77"abgerufen $line. Das Hinzufügen von 0 (oder 0,0 für gute alte C-Programmierer) hat geholfen.

Steffen Moeller
quelle
0

Perl ist schwach typisiert und kontextbasiert. Viele Skalare können abhängig von den verwendeten Operatoren sowohl als Zeichenfolgen als auch als Zahlen behandelt werden. $a = 7*6; $b = 7x6; print "$a $b\n";
Du verstehst 42 777777.

Es gibt jedoch einen subtilen Unterschied. Wenn Sie numerische Daten aus einer Textdatei in eine Datenstruktur einlesen und dann mit anzeigen Data::Dumper, werden Sie feststellen, dass Ihre Zahlen in Anführungszeichen stehen. Perl behandelt sie intern als Zeichenfolgen.
Lesen Sie : $my_hash{$1} = $2 if /(.+)=(.+)\n/;.
Dump:'foo' => '42'

Wenn Sie nicht zitierte Zahlen im Speicherauszug haben möchten:
Lesen Sie : $my_hash{$1} = $2+0 if /(.+)=(.+)\n/;.
Dump:'foo' => 42

Nachdem $2+0Perl bemerkt hat, dass Sie $ 2 als Zahl behandelt haben, weil Sie einen numerischen Operator verwendet haben.

Ich habe dies bemerkt, als ich versucht habe, zwei Hashes mit zu vergleichen Data::Dumper.

SzG
quelle