File Coverage

blib/lib/Lingua/PT/Words2Nums.pm
Criterion Covered Total %
statement 40 40 100.0
branch 8 8 100.0
condition 1 2 50.0
subroutine 5 5 100.0
pod 1 1 100.0
total 55 56 98.2


line stmt bran cond sub pod time code
1             package Lingua::PT::Words2Nums;
2              
3 4     4   104421 use 5.006;
  4         16  
  4         258  
4 4     4   39 use strict;
  4         6  
  4         166  
5 4     4   21 use warnings;
  4         13  
  4         1437  
6              
7             require Exporter;
8              
9             our @ISA = qw(Exporter);
10              
11             our %EXPORT_TAGS = ( 'all' => [ qw(
12             word2num
13             ) ] );
14              
15             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
16              
17             our @EXPORT = qw(
18             );
19              
20             our $VERSION = '1.04';
21              
22             =head1 NAME
23              
24             Lingua::PT::Words2Nums - Converts Portuguese words to numbers
25              
26             =head1 SYNOPSIS
27              
28             use Lingua::PT::Words2Nums qw/word2num/;
29              
30             $result = num2word("cinco");
31             # $result now holds 5
32              
33             =head1 DESCRIPTION
34              
35             Words2Nums converts Portuguese words to numbers (works with numbers
36             ranging from 0 to 999.999.999.999.999.999).
37              
38             Not all possible ways to write a number have been implemented (some
39             people write "nove mil novecentos e um", some people write "nove mil,
40             novecentos e um"; Words2Nums currently supports only the first way,
41             without commas; also, the word "bilião" is supported, but not "bilhão").
42              
43             =cut
44              
45             my (%values,@values,%bigvalues,@bigvalues);
46              
47             BEGIN {
48 4     4   184 %values = (
49             mil => 1000,
50              
51             novecentos => 900,
52             oitocentos => 800,
53             setecentos => 700,
54             seiscentos => 600,
55             quinhentos => 500,
56             quatrocentos => 400,
57             trezentos => 300,
58             duzentos => 200,
59             cem => 100,
60              
61             cento => 100,
62              
63             noventa => 90,
64             oitenta => 80,
65             setenta => 70,
66             sessenta => 60,
67             cinquenta => 50,
68             quarenta => 40,
69             trinta => 30,
70             vinte => 20,
71              
72             dezanove => 19,
73             dezoito => 18,
74             dezassete => 17,
75             dezasseis => 16,
76             quinze => 15,
77             catorze => 14,
78             treze => 13,
79             doze => 12,
80             onze => 11,
81             dez => 10,
82              
83             nove => 9,
84             oito => 8,
85             sete => 7,
86             seis => 6,
87             cinco => 5,
88             quatro => 4,
89             'três' => 3,
90             dois => 2,
91             um => 1,
92             );
93              
94 4         59 @values = sort {$values{$b} <=> $values{$a}} keys %values;
  624         929  
95              
96 4         23 %bigvalues = (
97             bili => 1000000000000,
98             milh => 1000000,
99             );
100              
101 4         16 @bigvalues = sort {$bigvalues{$b} <=> $bigvalues{$a}} keys %bigvalues;
  4         1831  
102              
103             }
104              
105             =head2 word2num
106              
107             Turns a word into a number
108              
109             $result = num2word("cinco");
110             # $result now holds 5
111              
112             =cut
113              
114             sub word2num {
115 10209   50 10209 1 44543 $_ = shift || return undef;
116 10209         19095 my $result = 0;
117              
118 10209         28318 for my $val (@bigvalues) {
119 20418         49550 my $expr = "${val}ões|${val}ão";
120              
121 20418 100       955430 if (s/(.+)mil(?=.*(?:$expr))//) {
122 49         111 my $big = $1;
123 49         79 for my $value (@values) {
124 1862         13750 $big =~ s/$value/
125 97         511 $result += ($values{$value} * $bigvalues{$val} * 1000)/e;
126             }
127             }
128              
129 20418 100       659164 if (s/(.+)(?:$expr)//) {
130 108         235 my $sma = $1;
131 108         161 for my $value (@values) {
132 4104         30228 $sma =~ s/$value/
133 194         921 $result += ($values{$value} * $bigvalues{$val})/e;
134             }
135             }
136              
137             }
138              
139 10209 100       64830 if (s/(.+?)mil//) {
140 8117         20471 my $thousands = $1;
141 8117 100       32017 if ($thousands =~ /^\s*e?\s*$/) {
142 2         4 $result += 1000;
143             }
144             else {
145 8115         16556 for my $value (@values) {
146 308370         2798014 $thousands =~ s/$value/$result += ($values{$value} * 1000)/e;
  8211         44593  
147             }
148             }
149             }
150              
151 10209         22524 for my $value (@values) {
152 387942         3419622 s/$value/$result += $values{$value}/e;
  27423         127817  
153             }
154              
155 10209         79191 $result;
156             }
157              
158             1;
159             __END__