Re: Converting quoted strings to numbers in array
by choroba (Cardinal) on Apr 23, 2017 at 20:49 UTC
|
For Perl, strings and numbers are different, even if it's easy to convert between them. A string can be specified in quotes, e.g.
'string'
"another string"
q(yet another)
qq<or like this>
etc. Numbers can be specified in different ways, too:
12
1_2
0b1100
0x0c
All of them are just different ways how to represent the number 12. The problem is that 0x0c as a string , i.e. in quotes, is not interpreted as a number, but as a string. To convert it to a number, you need to use the oct function:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
my @arr = qw( 10 10 20 0x47 1 30 45 45 );
my @converted = map /^0x/ && oct || $_, @arr;
say for @converted;
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
If you were dealing with a mixture of binary (as 0b...), hexadecimal (as 0x...), and octal strings,
e.g. in a loop, then oct would be useful.
When you know it's a hexadecimal string (e.g. /^0x/ && ...),
I'd use the hex function.
It makes your intent clear and obvious and, in my opinion, the code is far more readable.
The actual result is the same whichever you use:
$ perl -E 'say oct "0x47"; say hex "0x47"'
71
71
And just a word of warning, /^0x/ may not do what you want:
$ perl -E 'say "0x47_not_hex" =~ /^0x/ ? "is hex" : "is NOT hex"'
is hex
$ perl -E 'say "0x47_not_hex" =~ /^0x[0-9a-fA-F]+$/ ? "is hex" : "is N
+OT hex"'
is NOT hex
| [reply] [d/l] [select] |
|
|
The word oct in my reply was a link. Have you clicked it and read the documentation?
> If EXPR happens to start off with 0x , interprets it as a hex string.
Maybe not the best name for such a function, but that's how it is.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] |
Re: Converting quoted strings to numbers in array
by AnomalousMonk (Archbishop) on Apr 23, 2017 at 22:39 UTC
|
After you've finished the problem you've set youself in the OP, consider what it would take to be able to freely intermix literal numbers and quoted numbers of any (supported) base:
123, '123', 0123, '0123', 0x123, '0x123', 0b1101, '0b1101'
(Hint: try some simple experimentation with oct; be sure to read its documentation thoroughly.)
Then also support negative and positive intermixed literal/quoted numbers:
-123, '-123', -0123, '-0123', -0x123, '-0x123', -0b1101, '-0b1101'
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
Re: Converting quoted strings to numbers in array
by Marshall (Canon) on Apr 24, 2017 at 05:48 UTC
|
The "qw" means quote word(s). This is aide to help in typing in lots of strings. That's all it does.
If you want to mix decimal,octal,hex numbers in some @a=qw(...),see below. Just ask Perl to evaluate what that string means in terms of an actual "number".
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @array_of_strings = qw (10 20 0x47 1 30 0b011);
#
# "qw" is "quote word(s), this is the same as:
# my @array_of_strings = ("10","20","0x47","1","30","0b011");
print Dumper \@array_of_strings; # only string context not "numbers"
my @array = map{eval $_}@array_of_strings;
# or my @array = map{eval $_} qw (10 20 0x47 1 30 0b011);
print Dumper \@array;
__END__
prints:
$VAR1 = [
'10',
'20',
'0x47',
'1',
'30',
'0b011'
];
$VAR1 = [
10,
20,
71,
1,
30,
3
];
Update: added a binary number to example.
| [reply] [d/l] |
Re: Converting quoted strings to numbers in array
by Anonymous Monk on Apr 23, 2017 at 21:17 UTC
|
my @arr = ( 1, 2, 3, 0x47 ); are numeric literals, see Scalar value constructors. In the source code they can look like 12345 or 4_294_967_296 or 0xff or 0377 or 0b011011 and will all be converted to numbers and stored as numbers. my @arr = qw/ 1 2 3 0x47 /; are strings, see qw//, it's the same as writing my @arr = ( "1", "2", "3", "0x47" );. In the source code, 0x47 is different from "0x47", the first one means 71 and the second one is a string with four characters. Strings will only be automatically converted to numbers if they are plain integers. If you want to know if a string will automatically convert to a number, you can use looks_like_number from Scalar::Util. "0x47" is not a plain integer, it's got an x character. Use oct to convert that string to a number, oct it does octal, 0x123 and 0b101 formats, or use hex which only does hexadecimal. | [reply] [d/l] [select] |
|
|
Strings will only be automatically converted to numbers if they are plain integers.
Or decimals, or scientific notation, or "Inf". But not hex or 12_34 notation, or 0b..., and octal numbers (0123 == 83) won't be recognized as such ("0123" == 123).
| [reply] [d/l] [select] |
Re: Converting quoted strings to numbers in array
by pritesh_ugrankar (Monk) on Apr 24, 2017 at 12:45 UTC
|
Hi,
Thank you for taking time to reply to my query. Using the suggestions here, I have come up with the following solution.
use strict;
use warnings;
my @arr = qw(10 20 0b1101 0xF 023);
my @converted = map {$_ =~ /^0/ ? oct($_) : $_ } @arr;
print "@arr\n";
print "@converted\n";
The output seems satisfactory:
C:\>perl practice.pl
10 20 0b1101 0xF 023
10 20 13 15 19
I'm not sure if using a ternary operator inside map is considered un idiomatic, but it seems to work.
Thank you all, thank you very much. This I know would seem trivial to you, but it's fixing something I've been fighting in my head from a while.
Thinkpad T430 with Ubuntu 16.04.2 running perl 5.24.1 thanks to plenv!!
| [reply] [d/l] [select] |
|
|
use Data::Dump;
my @arr = qw/ 10 20 0b1101 0xF 023 /;
dd @arr;
my @converted = map {/^0/ ? oct : $_} @arr;
dd @converted;
__END__
(10, 20, "0b1101", "0xF", "023")
(10, 20, 13, 15, 19)
| [reply] [d/l] [select] |
Re: Converting quoted strings to numbers in array
by Anonymous Monk on Apr 24, 2017 at 17:08 UTC
|
use Data::Dumper;
use Number::Convert;
my @arr = map Number::Convert->new($_), (10, 20, 0b010101, 0xF, 023);
print $_->ToDecimal, $/ for @arr;
| [reply] [d/l] |