Як перетворити рядок на число в Perl?


86

У мене є рядок, який містить десяткове значення, і мені потрібно перетворити цей рядок у змінну з плаваючою комою. Отже, прикладом рядка, який я маю, є "5.45", і я хочу еквівалент з плаваючою комою, щоб я міг додати .1 до нього. Я шукав в Інтернеті, але я бачу лише, як перетворити рядок у ціле число.


Питання потребує подальших деталей. Чи рядок складається лише з числівників? Буквено-цифрові? Гаразд, якщо альфи позбавлені? Чи існує конкретна мета для отриманого числа?
JGurtz 01.03.16

Відповіді:


90

Вам взагалі не потрібно перетворювати його:

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

26
5.55 не є цілим числом
OrangeDog 07.03.12

15
@OrangeDog ОП редагував запитання (через кілька місяців після розміщення цієї відповіді) - оригінальне запитання насправді містило номери з плаваючою комою.
Alnitak

1
як щодо порівнянь, коли в рядку є кома?
Рамі

[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;'
Рамі

73

Це просте рішення:

Приклад 1

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

Результат

123

Приклад 2

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

Результат

0

7
AFAIU це єдина відповідь на запитання
Кугар

4
Обережно, додаючи нуль до рядка. Якщо рядок починається з "inf" або з "nan", значення не буде дорівнювати нулю. Наприклад, моя $ var2 = "info123"; print $ var2 + 0: Результат буде: Inf
Родріго Де Альмейда Сікейра

Я робив foreach my $i ('00'..'15')і потрібно було прибрати провідні нулі в деяких місцях. Це 0+відливання до числа також досягає цього.
stevesliva

Очевидно, це не працює з шістнадцятковими рядками: '0x14C' + 0 призводить до 0 (arrggg)
Аллассо

41

Perl - це мова, заснована на контексті. Він не виконує свою роботу відповідно до даних, які ви йому надаєте. Натомість він визначає, як поводитися з даними на основі операторів, якими ви користуєтесь, та контексту, в якому ви їх використовуєте. Якщо ви робите цифри різними способами, ви отримуєте цифри:

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

Якщо ви робите рядки різного роду, ви отримуєте рядки:

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

Perl здебільшого придумує, що робити, і це переважно правильно. Інший спосіб сказати те саме: Perl більше дбає про дієслова, ніж про іменники.

Ви намагаєтесь щось зробити, а це не працює?


Вибачте за мою відсутність знань тут, але я не зовсім розумію ваш другий приклад. Ви ділите два числа, а потім множите їх, як / чому це призводить до рядка?
gideon

4
Я не множу числа. xОператор рядки реплікації.
brian d foy

3
Чи не повинно бути my $string = ( 45/2 ) x 3; # "22.522.522.5"з 45 замість 44? Інакше я не потрапляю
звідти, звідки береться

10

Google привів мене сюди під час пошуку того самого запитання, яке задав phill (сортування з плаваючою точкою), тому я зрозумів, що варто було б розмістити відповідь, незважаючи на те, що нитка стара. Я вперше в Perl, і я все ще обмотую його голову, але вислів Брайана д Фоя "Perl більше дбає про дієслова, ніж про іменники". вгорі справді б'є цвях на голові. Вам не потрібно перетворювати рядки на плаваючі, перш ніж застосовувати сортування. Вам потрібно сказати сортуванню, щоб сортувати значення як числа, а не рядки. тобто

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

Детальніше про сортування див. На http://perldoc.perl.org/functions/sort.html


8

Наскільки я розумію, int () не призначений як функція "приведення" для позначення типу даних, він тут просто використовується (ab) для визначення контексту як арифметичного. Раніше я (ab) використовував (0 + $ val) для того, щоб $ val оброблявся як число.


так, int()використовується "(ab) використовується"; зрозумів.
Sapphire_Brick

6
$var += 0

напевно те, що ти хочеш. Однак зауважте, якщо $ var не є рядком, який неможливо перетворити в числовий, ви отримаєте помилку, і $ var буде скинуто до 0 :

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

журнали

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

3

Perl насправді має лише три типи: скаляри, масиви та хеші. І навіть ця різниця спірна. ;) Спосіб обробки кожної змінної залежить від того, що ви з нею робите:

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


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

5
Perl має набагато більше типів, ніж, але для одиничних значень це просто одне значення.
brian d foy

1

При порівнянні важливо, якщо скаляр є числом рядка. І це не завжди можна вирішити. Я можу повідомити про випадок, коли perl отримав поплавок у "науковому" позначенні і використав той самий кілька рядків нижче для порівняння:

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

І тут $valне трактувалось як числове, наприклад, "2e-77"отримане з $line. Додавання 0 (або 0,0 для хороших програмістів ole C) допомогло.


0

Perl слабко набраний і заснований на контексті. Багато скалярів можуть трактуватися як як рядки, так і як числа, залежно від використовуваних операторів. $a = 7*6; $b = 7x6; print "$a $b\n";
Ви отримуєте 42 777777.

Однак є незначна різниця. Коли ви читаєте числові дані з текстового файлу в структурі даних, а потім переглядаєте їх за допомогою Data::Dumper, ви помітите, що ваші номери вказані в лапках. Perl розглядає їх внутрішньо як струни.
Читайте: $my_hash{$1} = $2 if /(.+)=(.+)\n/;.
Звалище:'foo' => '42'

Якщо ви хочете некотируваних номера в відвал:
Read: $my_hash{$1} = $2+0 if /(.+)=(.+)\n/;.
Звалище:'foo' => 42

Після того, як $2+0Perl зауважує, що ви обробили $ 2 як число, оскільки ви використовували числовий оператор.

Я це помітив, намагаючись порівняти два хеші Data::Dumper.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.