ฉันจะแปลงสตริงเป็นตัวเลขใน Perl ได้อย่างไร


86

ฉันมีสตริงที่มีค่าทศนิยมและฉันต้องแปลงสตริงนั้นเป็นตัวแปรทศนิยม ตัวอย่างของสตริงที่ฉันมีคือ "5.45" และฉันต้องการค่าทศนิยมเพื่อที่ฉันจะได้เพิ่ม. 1 เข้าไป ฉันได้ค้นหาในอินเทอร์เน็ต แต่ฉันเห็นเพียงวิธีการแปลงสตริงเป็นจำนวนเต็ม


คำถามต้องการรายละเอียดเพิ่มเติม สตริงประกอบด้วยตัวเลขเท่านั้นหรือไม่ ตัวอักษรและตัวเลข? ตกลงถ้าอัลฟ่าถูกปล้น? มีจุดประสงค์เฉพาะสำหรับจำนวนผลลัพธ์หรือไม่?
JGurtz

คำตอบ:


91

คุณไม่จำเป็นต้องแปลงเลย:

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

15
@OrangeDog OP แก้ไขคำถาม (หลายเดือนหลังจากโพสต์คำตอบนี้) - คำถามเดิมมีตัวเลขทศนิยมอยู่ในนั้น
Alnitak

1
แล้วการเปรียบเทียบเมื่อสตริงมีเครื่องหมายจุลภาคอยู่ล่ะ?
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

นี่เป็นวิธีง่ายๆ:

ตัวอย่าง 1

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

ผลลัพธ์

123

ตัวอย่าง 2

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

ผลลัพธ์

0

7
AFAIU นี่คือคำตอบเดียวสำหรับสิ่งที่ถูกถาม
Cougar

4
ระวังเมื่อเพิ่มศูนย์ลงในสตริง หากสตริงเริ่มต้นด้วย "inf" หรือด้วย "nan" ค่าจะไม่เป็นศูนย์ เช่น my $ var2 = "info123"; พิมพ์ $ var2 + 0: ผลลัพธ์จะเป็น: Inf
Rodrigo De Almeida Siqueira

ฉันกำลังทำforeach my $i ('00'..'15')และจำเป็นต้องลบเลขศูนย์นำหน้าในบางตำแหน่ง นี้0+หล่อไปยังหมายเลขที่ยังประสบความสำเร็จว่า
stevesliva

เห็นได้ชัดว่าสิ่งนี้ใช้ไม่ได้กับสตริงเลขฐานสิบหก: '0x14C' + 0 ผลลัพธ์ใน 0 (arrggg)
Allasso

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 ไม่ใช่หรือ? ไม่งั้นฉันจะไม่เข้าใจว่า '.5 มาจากไหนในผลลัพธ์ ...
วิคสเตอร์

10

Google นำฉันมาที่นี่ในขณะที่ค้นหาคำถามเดียวกันที่ phill ถาม (การเรียงลำดับลอย) ดังนั้นฉันจึงคิดว่ามันจะคุ้มค่าที่จะโพสต์คำตอบแม้ว่าเธรดจะเก่าก็ตาม ฉันยังใหม่กับ perl และฉันยังคงเอาหัวไปพันรอบ ๆ มัน แต่คำพูดของ brian d foy "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 ()ไม่ได้มีไว้ให้เป็นฟังก์ชัน 'cast' สำหรับการกำหนดประเภทข้อมูลมันเป็นเพียงการใช้ (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'

หากคุณต้องการหมายเลข unquoted ในการถ่ายโอนข้อมูล: อ่าน:
การถ่ายโอนข้อมูล:$my_hash{$1} = $2+0 if /(.+)=(.+)\n/;
'foo' => 42

หลังจากที่$2+0Perl สังเกตเห็นว่าคุณถือ $ 2 เป็นตัวเลขเพราะคุณใช้ตัวดำเนินการตัวเลข

Data::Dumperผมสังเกตเห็นนี้ในขณะที่พยายามที่จะเปรียบเทียบกับสอง hashes

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.