File Coverage

blib/lib/Lingua/JA/Numbers.pm
Criterion Covered Total %
statement 1178 1181 99.7
branch 57 76 75.0
condition 27 44 61.3
subroutine 360 360 100.0
pod 8 10 80.0
total 1630 1671 97.5


line stmt bran cond sub pod time code
1             package Lingua::JA::Numbers;
2              
3 7     7   63406 use 5.008001;
  7         20  
  7         339  
4 7     7   34 use strict;
  7         8  
  7         194  
5 7     7   27 use warnings;
  7         17  
  7         165  
6 7     7   2944 use utf8;
  7         48  
  7         28  
7              
8             our $VERSION = sprintf "%d.%02d", q$Revision: 0.5 $ =~ /(\d+)/g;
9             require Exporter;
10             our @ISA = qw(Exporter);
11             our @EXPORT = qw(
12             ja2num num2ja num2ja_ordinal ja_to_number number_to_ja number_to_ja_ordinal
13             );
14             our %EXPORT_TAGS = ( 'all' => [ @EXPORT, qw(to_string) ] );
15             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
16              
17             use overload
18 7         91 q("") => \&stringify,
19             q(0+) => \&numify,
20             fallback => 1,
21 7     7   8051 ;
  7         5542  
22              
23             sub new{
24 5     5 1 22 my $class = shift;
25 5         9 my ($str, $opt) = @_;
26 5 50       19 my $val = $str ? ja2num($str, $opt) : '';
27 5   50     153 return bless {
28             val => $val,
29             opt => $opt || { style => 'kanji' },
30             }, $class;
31             }
32              
33             sub parse{
34 1     1 1 2 my $self = shift;
35 1         3 my ($str, $opt) = @_;
36 1   33     4 $opt ||= $self->{opt};
37 1         3 $self->{val} = ja2num($str, $opt);
38 1         63 $self->{opt} = $opt;
39 1         30 $self
40             }
41              
42             sub opt{
43 7     7 1 9 my $self = shift;
44 7         31 $self->{opt} = {
45 7         7 %{ $self->{opt} },
46             @_,
47             };
48             # use Data::Dumper;
49             # print Dumper $self;
50 7         16 return $self;
51             }
52              
53 1     1 1 436 sub numify { $_[0]->{val} };
54             *as_number = \&numify;
55 9     9 1 187 sub get_string { num2ja($_[0]->{val}, $_[0]->{opt}) };
56             *stringify = *as_string = \&get_string;
57 4     4 0 13 sub ordinal { num2ja_ordinal($_[0]->{val}, $_[0]->{opt}) };
58              
59             our $Zero = {
60             kanji => '零',
61             daiji => '零',
62             romaji => 'Zero',
63             katakana => 'ゼロ',
64             hiragana => 'ぜろ',
65             };
66             our $Point = {
67             kanji => '点',
68             daiji => '点',
69             romaji => 'Ten',
70             katakana => 'テン',
71             hiragana => 'てん',
72             };
73             our $Sign = {
74             kanji => {'+' => q(), '-' => '−'},
75             daiji => {'+' => q(), '-' => '−'},
76             romaji => {'+' => '+', '-' => '-'},
77             katakana => {'+' => 'プラス', '-' => 'マイナス'},
78             hiragana => {'+' => 'ぷらす', '-' => 'まいなす'},
79             };
80             our $Zero2Nine = {
81             kanji => [qw(〇 一 二 三 四 五 六 七 八 九)],
82             daiji => [qw(零 壱 弐 参 四 伍 六 七 八 九)],
83             daiji_h => [qw(零 壱 弐 参 肆 伍 陸 漆 捌 玖)],
84             romaji => [qw(Zero Ichi Ni San Yon Go Roku Nana Hachi Kyuu)],
85             katakana => [qw(ゼロ イチ ニ サン ヨン ゴ ロク ナナ ハチ キュウ)],
86             hiragana => [qw(ぜろ いち に さん よん ご ろく なな はち きゅう)],
87             };
88             our $Ten2Thou = {
89             kanji => [q(), qw(十 百 千)],
90             daiji => [q(), qw(拾 佰 阡)],
91             romaji => [q(), qw(Juu Hyaku Sen)],
92             katakana => [q(), qw(ジュウ ヒャク セン)],
93             hiragana => [q(), qw(じゅう ひゃく せん)],
94             };
95             our $Hugenums = {
96             kanji => [qw(極 恒河沙 阿僧祇 那由他 不可思議 無量大数)], # manman-shin
97             daiji => [qw(極 恒河沙 阿僧祇 那由他 不可思議 無量大数)], # manman-shin
98             romaji => [qw(Goku Kougasha Asougi Nayuta Fukashigi Muryoutaisuu) ],
99             katakana => [qw(ゴク コウガシャ アソウギ ナユタ フカシギ ムリョウタイスウ)],
100             hiragana => [qw(ごく こうがしゃ あそうぎ なゆた ふかしぎ むりょうたいすう)],
101             },
102              
103             our $Suffices = {
104             kanji => [q(), qw(万 億 兆 京 垓 禾予 穣 溝 澗 正 載),
105             @{ $Hugenums->{kanji} }],
106             daiji => [q(), qw(萬 億 兆 京 垓 禾予 穣 溝 澗 正 載),
107             @{ $Hugenums->{kanji} }],
108             romaji => [q(), qw(Man Oku Chou Kei Gai Jo Jou Kou Kan Sei Sai Goku),
109             @{ $Hugenums->{romaji} }],
110             katakana => [q(), qw(マン オク チョウ ケイ ガイ ジョ ジョウ コウ ジュン セイ サイ),
111             @{ $Hugenums->{katakana} }],
112             hiragana => [q(), qw(まん おく ちょう けい がい じょ じょう こう じゅん せい さい),
113             @{ $Hugenums->{hiragana} }],
114             };
115              
116             our %RE_Kana_Fix = (
117             SanHyaku => 'Sanbyaku', 'さんひゃく' => 'さんびゃく', 'サンヒャク' => 'サンビャク',
118             RokuHyaku => 'Roppyaku', 'ろくひゃく' => 'ろっぴゃく', 'ロクヒャク' => 'ロッピャク',
119             HachiHyaku => 'Happyaku', 'はちひゃく' => 'はっぴゃく', 'ハチヒャク' => 'ハッピャク',
120             SanSen => 'Sanzen', 'さんせん' => 'さんぜん', 'サンセン' => 'サンゼン',
121             HachiSen => 'Hassen', 'はちせん' => 'はっせん', 'ハチセン' => 'ハッセン',
122             );
123             our $RE_Kana_Fix = join("|", keys %RE_Kana_Fix);
124              
125             sub num2ja{
126 7     7   4443 no warnings 'uninitialized';
  7         12  
  7         10178  
127             # use bignum;
128 506     506 1 287812 my ($num, $opt) = @_;
129             # warn $num;
130 506   100     2507 my $style = $opt->{style} || 'kanji';
131              
132 506 50       1612 my $zero = $opt->{zero} ? $opt->{zero}
133             : $Zero->{$style} ;
134 506 100       6948 return $zero unless $num;
135 501         8063 my ($sig, $int, $fract, $exp)
136             = ($num =~ /([+-])?(\d+)(?:\.(\d+))?(?:[eE]([+-]?\d+))?/io);
137             # warn join ",", ($num, $sig, $int, $fract, $exp);
138             my $scientific = sub {
139 32     32   106 my $first = substr($int, 0, 1, '');
140 32         55 $exp += length($int);
141 32         188 return num2ja("$sig$first.$int$fract" . "e$exp", $opt);
142 501         11925 };
143 501         716 my $manman = '';
144 501 100 100     1695 if (length($int) > 48 and $opt->{manman}) {
145 48 100       1535 if (length($int) > 96) { # Resort to Scientific Notation
146 4         11 return $scientific->()
147             }
148 44         460 $int =~ s/(.*)(.{48})\z/$2/o;
149 44         123 my $huge = $1;
150 44         58 my @shins;
151 44         482 push @shins, $1 while $huge =~ s/(\d{8})$//g; # idea from commify hack
152 44 100       140 push @shins, $huge if $huge;
153 44         72 my $suffix = 0;
154 44         81 for my $shin (@shins) {
155 164 50       285 if ($shin eq '00000000') {
156 0         0 $suffix++;
157 0         0 next;
158             }
159 164         248 $manman = num2ja($shin, $opt) . $Hugenums->{$style}[$suffix++] . $manman;
160             }
161             } else {
162 453 100       981 if (length($int) > 72) { # Resort to Scientific Notation
163 28         82 return $scientific->();
164             }
165             }
166 469 50       1501 my $sign = $opt->{sign} ? $opt->{sign} : $Sign->{$style};
167 469 100       2169 my $zero2nine = $opt->{zero2nine} ? $opt->{zero2nine}
    100          
    50          
168             : $opt->{daiji} >= 2 ? $Zero2Nine->{daiji_h}
169             : $opt->{daiji} == 1 ? $Zero2Nine->{daiji}
170             : $Zero2Nine->{$style};
171 469 100 66     2543 my $ten2thou = $opt->{ten2thou} ? $opt->{ten2thou}
    50          
172             : $opt->{daiji} || $opt->{daiji_h} ? $Ten2Thou->{daiji}
173             : $Ten2Thou->{$style} ;
174 469 100 66     2462 my $suffices = $opt->{suffices} ? $opt->{suffices}
    50          
175             : $opt->{daiji} || $opt->{daiji_h} ? $Suffices->{daiji}
176             : $Suffices->{$style} ;
177 469         669 my ($seisuu, $shousuu, $beki) = ();
178 469         439 my @shins;
179 469         5327 push @shins, $1 while $int =~ s/(\d{4})$//g; # idea from commify hack
180 469 100       929 push @shins, $int if $int;
181 469         619 my $suffix = 0;
182 469         715 for my $shin (@shins) {
183 1788 100       2995 if ($shin eq '0000') {
184 1         1 $suffix++;
185 1         2 next;
186             }
187 1787         1515 my $sens = '';
188 1787         1398 my $keta = 0;
189             # warn $man;
190 1787         3239 for my $digit (reverse split //, $shin) {
191 6713 100 66     17768 if ($opt->{fixed4} or $opt->{with_arabic}) {
192 10 50       14 $sens =
193             ($opt->{with_arabic} ? $digit : $zero2nine->[$digit])
194             . $sens;
195             } else {
196 6703 100 100     17405 my $suuji =
197             ($digit == 1
198             and !$opt->{p_one}
199             and $keta > 0) ? ''
200             : $zero2nine->[$digit];
201 6703 100       13132 $sens = $suuji . $ten2thou->[$keta] . $sens
202             if $digit != 0;
203             }
204 6713         6635 $keta++;
205             }
206             # $sens or next;
207 1787         4055 $seisuu = $sens . $suffices->[$suffix++] . $seisuu;
208             }
209 469         1135 my $result = $sign->{$sig} . $manman . $seisuu;
210 469   66     968 $result ||= $zero;
211 469 100       868 if ($fract) {
212 84         507 while ($fract =~ /(\d)/g) {
213 4068         8004 $shousuu .= $zero2nine->[$1];
214             }
215 84 50       318 my $point = $opt->{point} ? $opt->{point}
216             : $Point->{$style};
217 84         230 $result .= $point . $shousuu;
218             }
219 469 100       798 if ($exp) {
220 32 50       225 $result .=
    50          
    50          
221             $opt->{romaji} ? 'KakeruJuNo' . num2ja($exp, $opt) .'Jou'
222             : $opt->{katakana} ? 'カケルジュウノ' . num2ja($exp, $opt) .'ジョウ'
223             : $opt->{hiragana} ? 'かけるじゅうの' . num2ja($exp, $opt) .'じょう'
224             : '掛ける十の' . num2ja($exp, $opt) . '乗';
225             }
226 469 100       1881 if ($style =~ /(?:romaji|[k|g]ana)$/){
227 68         4934 $result =~ s/($RE_Kana_Fix)/$RE_Kana_Fix{$1}/ig;
228             }
229 469         3605 return $result;
230             }
231              
232             *number_to_ja = \&num2ja;
233              
234             our $Ordinal = {
235             kanji => '番',
236             romaji => 'Ban',
237             hiragana => 'ばん',
238             katakana => 'バン',
239             };
240              
241             sub num2ja_ordinal{
242 4     4 0 7 my ($num, $opt) = @_;
243 4   50     10 my $style = $opt->{style} || 'kanji';
244 4   33     19 my $ordinal = $opt->{ordinal} || $Ordinal->{$style};
245 4         5 return num2ja(@_) . $ordinal;
246             }
247             *number_to_ja_ordinal = \&num2ja_ordinal;
248              
249              
250             our %RE_Points = (
251             '.' => '.',
252             '点' => '.',
253             'てん' => '.',
254             );
255             our $RE_Points = join ('|', keys %RE_Points);
256              
257             our %RE_Zero2Nine = (
258             '零' => 0, '〇' => 0, 'ぜろ' => 0, 'れい' => 0, Zero => 0,
259             '一' => 1, '壱' => 1, 'いち' => 1, Ichi => 1,
260             '二' => 2, '弐' => 2, 'に' => 2, Ni => 2,
261             '三' => 3, '参' => 3, 'さん' => 3, San => 3,
262             '四' => 4, '肆' => 4, 'し' => 4, 'よん' => 4, Shi => 4, Yon => 4,
263             '五' => 5, '伍' => 5, 'ご' => 5, Go => 5,
264             '六' => 6, '陸' => 6, 'ろく' => 6, Roku => 6,
265             '七' => 7, '漆' => 7, 'なな' => 7, 'しち' => 7, Nana => 7, Shichi => 7,
266             '八' => 8, '捌' => 8, 'はち' => 8, Hachi => 8,
267             '九' => 9, '玖' => 9, 'きゅう' => 9, Kyuu => 9,
268             );
269             our $RE_Zero2Nine = join ('|', keys %RE_Zero2Nine);
270              
271             our %RE_Ten2Thou = (
272             '十' => 1, '拾' => 1, 'じゅう' => 1, Juu => 1,
273             '百' => 2, '佰' => 2, 'ひゃく' => 2, Hyaku => 2,
274             '千' => 3, '阡' => 3, 'せん' => 3, Sen => 3,
275             );
276             our $RE_Ten2Thou = join ('|', keys %RE_Ten2Thou);
277              
278             our %RE_Suffices = (
279             '万' => 4, '萬' => 4, 'まん' => 4, Man => 4,
280             '億' => 8, 'おく' => 8, Oku => 8,
281             '兆' => 12, 'ちょう' => 12, Chou => 12,
282             '京' => 16, 'けい' => 16, Kei => 16,
283             '垓' => 20, 'がい' => 20, Gai => 20,
284             '禾予' => 24, 'じょ' => 24, Jo => 24,
285             '穣' => 28, 'じょう' => 28, Jou => 28,
286             '溝' => 32, 'こう' => 32, Kou => 32,
287             '澗' => 36, 'かん' => 36, Kan => 36,
288             '正' => 40, 'せい' => 40, Sei => 40,
289             '載' => 44, 'さい' => 44, Sai => 44,
290             '極' => 48, 'ごく' => 48, Goku => 48,
291             '恒河沙' => 52, 'こうがしゃ' => 52, Kougasha => 52,
292             '阿僧祇' => 56, 'あそうぎ' => 56, Asougi => 56,
293             '那由他' => 60, 'なゆた' => 60, Nayuta => 60,
294             '不可思議' => 64, 'ふかしぎ' => 64, Fukashigi => 64,
295             '無量大数' => 68, 'むりょうたいすう' => 68, Muryoutaisuu => 68,
296             );
297             our $RE_Suffices = join ('|', keys %RE_Suffices);
298              
299             our %RE_Hugenums = (
300             '極' => 48, 'ごく' => 48, Goku => 48,
301             '恒河沙' => 56, 'こうがしゃ' => 56, Kougasha => 56,
302             '阿僧祇' => 64, 'あそうぎ' => 64, Asougi => 64,
303             '那由他' => 72, 'なゆた' => 72, Nayuta => 72,
304             '不可思議' => 80, 'ふかしぎ' => 80, Fukashigi => 80,
305             '無量大数' => 88, 'むりょうたいすう' => 88, Muryoutaisuu => 88,
306             );
307             our $RE_Hugenums = join ('|', keys %RE_Hugenums);
308              
309             our %RE_Fraction = (
310             '割' => 1, 'わり' => 1,
311             '分' => 2, 'ぶ' => 2,
312             '厘' => 3, 'りん' => 3,
313             '毛' => 4, 'もう' => 4,
314             '糸' => 4, 'し' => 4, '絲' => 4,
315             '忽' => 5, 'こつ' => 5,
316             '微' => 6, 'び' => 6,
317             '繊' => 7, 'せん' => 7,
318             '沙' => 8, 'しゃ' => 8,
319             '塵' => 9, 'じん' => 9,
320             '埃' => 10, 'あい' => 10,
321             '渺' => 11, 'びょう' => 11,
322             '漠' => 12, 'ばく' => 12,
323             '模糊' => 13, 'もこ' => 13,
324             '逡巡' => 14, 'しゅんじゅん' => 14,
325             '須臾' => 15, 'しゅゆ' => 15,
326             '瞬息' => 16, 'しゅんそく' => 16,
327             '弾指' => 17, 'だんし' => 17,
328             '刹那' => 18, 'せつな' => 18,
329             '六徳' => 19, 'りっとく' => 19,
330             '空虚' => 20, 'くうきょ' => 20,
331             '清浄' => 21, 'せいじょう' => 21, '空' => 21, 'くう' => 21,
332             '清' => 22, 'せい' => 22,
333             '浄' => 23, 'じょう' => 23,
334             '阿頼耶' => 24, 'あらや' => 24,
335             '阿摩羅' => 25, 'あまら' => 25,
336             '涅槃寂靜' =>26, 'ねはんじゃくじょう' => 26,
337             );
338             our $RE_Fraction = join ('|', keys %RE_Fraction);
339              
340             our %RE_Op = (
341             '掛ける' => '*', 'かける' => '*', Kakeru => '*',
342             '割る' => '/', 'わる' => '/', Waru => '/',
343             '足す' => '+', 'たす' => '+', Tasu => '+', 'ぷらす' => '+',
344             'と' => '+',
345             '引く' => '-', 'ひく' => '-', Hiku => '-', 'まいなす' => '-',
346             );
347             our $RE_Op = join('|' => map { quotemeta($_) } keys %RE_Op);
348             our $RE_Numerals =
349             qr{(?:\d
350             |$RE_Zero2Nine|$RE_Ten2Thou|$RE_Suffices|$RE_Fraction|$RE_Points)+}ixo;
351             our %RE_Fix_Kana = reverse %RE_Kana_Fix;
352             our $RE_Fix_Kana = join("|", keys %RE_Fix_Kana);
353              
354             sub ja2num{
355 6     6   35 no warnings 'uninitialized';
  6         8  
  6         477  
356 276     276 1 3841 my ($ja, $opt) = @_;
357             # https://twitter.com/Nyaboo/status/575196780993761280
358 276 100       3117 if ($ja !~ /[+\-\.\deE]/) {
359 6     6   28 no warnings 'numeric';
  6         8  
  6         603  
360 250         863 my $num = $ja + 0;
361 250 50       660 return $num if $num;
362             }
363 276 50       613 $ja or return; # or it croaks under -T @ eval
364 276         2387 $ja =~ s/[\s\x{3000}]//g;
365 6     6   28 $ja =~ tr[0-9][0-9];
  6         10  
  6         70  
  276         4097  
366 276         3355 $ja =~ tr[ァ-ン][ぁ-ん];
367 276         26962 $ja =~ s/($RE_Fix_Kana)/$RE_Fix_Kana{ucfirst $1}/igx;
368 276         13351 $ja =~ s{ (?:の|ノ|No)($RE_Numerals)(?:乗|じょう|ジョウ|Jou) }
369 32         129 { "**" . $1 }iegx;
370 276         56654 $ja =~ s{ ($RE_Numerals) }{ _ja2num($1, $opt) }iegx;
  340         6479  
371 276         19849 $ja =~ s{ ($RE_Op) }{ $RE_Op{ucfirst $1} }igx;
372 276         1480 $ja =~ tr[()+−×÷][\(\)\+\-\*\/];
373             # to be secure; that way no dangerous ops are passed
374 276         852 $ja =~ tr/[G-Z]//d;
375 276     5   19984 my $result = eval qq{ use bignum; $ja};
  5     5   34  
  5     4   7  
  5     4   18  
  5     3   26  
  5     2   7  
  5     2   20  
  4     2   20  
  4     2   8  
  4     2   17  
  4     2   18  
  4     2   6  
  4     2   16  
  3     2   13  
  3     2   4  
  3     2   15  
  2     2   13  
  2     2   3  
  2     2   10  
  2     2   18  
  2     2   3  
  2     2   13  
  2     2   11  
  2     2   2  
  2     2   10  
  2     2   11  
  2     2   2  
  2     2   9  
  2     2   11  
  2     2   2  
  2     2   10  
  2     2   14  
  2     2   3  
  2     2   10  
  2     2   10  
  2     2   2  
  2     2   13  
  2     2   11  
  2     2   3  
  2     2   9  
  2     2   11  
  2     2   3  
  2     2   9  
  2     2   14  
  2     2   3  
  2     2   15  
  2     2   15  
  2     2   3  
  2     2   12  
  2     2   12  
  2     2   4  
  2     2   9  
  2     2   13  
  2     2   16  
  2     2   11  
  2     2   16  
  2     2   3  
  2     2   12  
  2     2   10  
  2     2   4  
  2     2   9  
  2     2   13  
  2     3   2  
  2     3   62  
  2     4   11  
  2     4   2  
  2     4   7  
  2     4   13  
  2     4   2  
  2     4   9  
  2     4   10  
  2     4   3  
  2     4   7  
  2     4   12  
  2     4   4  
  2     4   103  
  2     4   11  
  2     4   2  
  2     4   8  
  2     4   12  
  2     4   4  
  2     4   9  
  2     4   11  
  2     4   3  
  2     4   10  
  2     4   15  
  2     4   4  
  2     4   11  
  2     4   11  
  2     4   2  
  2     3   11  
  2     3   12  
  2     3   2  
  2     3   10  
  2     3   14  
  2     3   2  
  2     1   8  
  2     1   13  
  2     1   3  
  2     1   9  
  2     1   13  
  2     1   2  
  2     1   10  
  2     1   11  
  2     1   3  
  2     1   10  
  2     1   11  
  2     1   4  
  2     1   10  
  2     1   11  
  2     1   3  
  2     1   9  
  2     1   12  
  2     1   2  
  2     1   9  
  2     1   12  
  2     1   3  
  2     1   9  
  2     1   14  
  2     1   4  
  2     1   10  
  2     1   11  
  2     1   2  
  2     1   9  
  2     1   11  
  2     1   3  
  2     1   9  
  2     1   11  
  2     1   2  
  2     1   10  
  2     1   13  
  2     1   3  
  2     1   9  
  2     1   12  
  2     1   4  
  2     1   9  
  2     1   15  
  2     1   2  
  2     1   10  
  2     1   12  
  2     1   4  
  2     1   10  
  2     1   18  
  2     1   2  
  2     1   13  
  2     1   12  
  2     1   3  
  2     1   11  
  2     1   14  
  2     1   5  
  2     1   12  
  2     1   13  
  2     1   4  
  2     1   11  
  2     1   11  
  2     1   2  
  2     1   10  
  2     1   13  
  2     1   4  
  2     1   19  
  2     1   17  
  2     1   4  
  2     1   14  
  2     1   9  
  2     1   4  
  2     1   8  
  2     1   17  
  2     1   3  
  2     1   80  
  2         9  
  2         3  
  2         7  
  2         16  
  2         3  
  2         12  
  2         10  
  2         3  
  2         9  
  2         14  
  2         4  
  2         12  
  2         12  
  2         5  
  2         9  
  2         10  
  2         5  
  2         8  
  3         23  
  3         5  
  3         16  
  3         18  
  3         5  
  3         15  
  4         21  
  4         7  
  4         16  
  4         22  
  4         6  
  4         21  
  4         19  
  4         6  
  4         15  
  4         22  
  4         5  
  4         17  
  4         19  
  4         8  
  4         16  
  4         21  
  4         6  
  4         18  
  4         22  
  4         5  
  4         17  
  4         21  
  4         6  
  4         20  
  4         22  
  4         10  
  4         19  
  4         20  
  4         8  
  4         17  
  4         21  
  4         7  
  4         17  
  4         26  
  4         6  
  4         20  
  4         20  
  4         7  
  4         18  
  4         24  
  4         8  
  4         18  
  4         18  
  4         6  
  4         16  
  4         24  
  4         8  
  4         18  
  4         20  
  4         5  
  4         15  
  4         21  
  4         5  
  4         24  
  4         18  
  4         6  
  4         16  
  4         18  
  4         7  
  4         16  
  4         21  
  4         6  
  4         16  
  4         23  
  4         7  
  4         19  
  4         20  
  4         8  
  4         14  
  4         22  
  4         4  
  4         18  
  4         22  
  4         6  
  4         15  
  4         17  
  4         8  
  4         16  
  3         15  
  3         6  
  3         13  
  3         13  
  3         6  
  3         13  
  3         15  
  3         5  
  3         14  
  3         17  
  3         5  
  3         89  
  3         18  
  3         5  
  3         15  
  3         16  
  3         5  
  3         13  
  1         5  
  1         1  
  1         4  
  1         7  
  1         2  
  1         5  
  1         8  
  1         2  
  1         6  
  1         6  
  1         2  
  1         5  
  1         5  
  1         2  
  1         4  
  1         5  
  1         1  
  1         3  
  1         5  
  1         2  
  1         4  
  1         6  
  1         1  
  1         4  
  1         5  
  1         2  
  1         28  
  1         5  
  1         2  
  1         5  
  1         5  
  1         33  
  1         4  
  1         10  
  1         3  
  1         7  
  1         5  
  1         1  
  1         4  
  1         5  
  1         2  
  1         5  
  1         5  
  1         1  
  1         4  
  1         5  
  1         2  
  1         4  
  1         5  
  1         1  
  1         5  
  1         6  
  1         2  
  1         6  
  1         4  
  1         2  
  1         4  
  1         5  
  1         1  
  1         4  
  1         5  
  1         1  
  1         18  
  1         7  
  1         2  
  1         5  
  1         6  
  1         2  
  1         3  
  1         7  
  1         2  
  1         5  
  1         5  
  1         1  
  1         4  
  1         5  
  1         3  
  1         4  
  1         4  
  1         2  
  1         4  
  1         6  
  1         1  
  1         7  
  1         5  
  1         1  
  1         4  
  1         7  
  1         2  
  1         6  
  1         4  
  1         1  
  1         4  
  1         7  
  1         1  
  1         6  
  1         5  
  1         2  
  1         4  
  1         7  
  1         1  
  1         6  
  1         8  
  1         3  
  1         6  
  1         9  
  1         2  
  1         7  
  1         8  
  1         1  
  1         5  
  1         10  
  1         2  
  1         9  
  1         7  
  1         3  
  1         5  
  1         10  
  1         3  
  1         8  
  1         7  
  1         3  
  1         5  
  1         10  
  1         2  
  1         8  
  1         7  
  1         1  
  1         5  
  1         10  
  1         3  
  1         8  
  1         6  
  1         2  
  1         6  
  1         9  
  1         3  
  1         7  
  1         6  
  1         2  
  1         5  
  1         11  
  1         3  
  1         8  
  1         7  
  1         3  
  1         5  
  1         7  
  1         2  
  1         5  
  1         5  
  1         1  
  1         4  
  1         6  
  1         1  
  1         6  
  1         5  
  1         1  
  1         5  
  1         6  
  1         1  
  1         6  
  1         5  
  1         1  
  1         4  
  1         6  
  1         1  
  1         6  
  1         5  
  1         1  
  1         3  
  1         6  
  1         1  
  1         6  
  1         5  
  1         1  
  1         5  
  1         8  
  1         1  
  1         6  
  1         5  
  1         1  
  1         5  
  1         7  
  1         1  
  1         5  
  1         4  
  1         1  
  1         3  
  1         10  
  1         2  
  1         8  
  1         5  
  1         1  
  1         4  
  1         7  
  1         3  
  1         5  
  1         4  
  1         1  
  1         4  
  1         7  
  1         2  
  1         6  
  1         5  
  1         1  
  1         5  
  1         6  
  1         1  
  1         6  
  1         6  
  1         1  
  1         4  
  1         6  
  1         1  
  1         6  
  1         4  
  1         2  
  1         4  
376 276 50 33     1438 $@ and $opt->{debug} and warn "$ja => $@";
377 276 50       1008 $opt->{debug} and warn qq{ja2num("$ja") == $result};
378 276         4576 return qq($result);
379             }
380             *ja_to_number = \&ja2num;
381              
382             sub _ja2num{
383 6     6   34332 no warnings 'uninitialized';
  6         11  
  6         4504  
384 504     504   1139 my ($ja, $opt) = @_;
385 504 50       1264 $ja or return;
386 504         949 my $manman = '';
387 504 100       1461 if ($opt->{manman}){ # wierd hack
388 220         10204 $ja =~ s{ \G(.*?)($RE_Hugenums) }
389 164         460 { my ($p, $q) = ($1, $2);
390 164   50     361 $p ||= 1;
391 164         313 $manman .= _ja2num($p, $opt) . "e" . $RE_Hugenums{$q} . '+';
392 164         13087 q();
393             }iegx;
394             }
395 504         64475 $ja =~ s{ ($RE_Zero2Nine) }{$RE_Zero2Nine{ucfirst $1}}igx;
396 504         40753 $ja =~ s{ (\d*)($RE_Ten2Thou) }
397 4799   100     10202 { my $n = $1 || 1;
398 4799         23815 $n.'e'.$RE_Ten2Thou{ucfirst $2}.'+' }iegx;
399 504         7207 $ja =~ s{ ([\d\+\-e]+)($RE_Fraction) }
400 0         0 { qq{($1)} . '*1e-' . $RE_Fraction{ucfirst $2} . '+'}iegx;
401 504         15359 $ja =~ s{ \G(.*?)\+?($RE_Suffices) }
402 1365   50     3211 { my $p = $1 || 1;
403 1365         35097 "($p)*1e" . $RE_Suffices{ucfirst $2} . '+'
404             }iegx;
405 504         7371 $ja =~ s{ ($RE_Points) }{ '.' }iegx;
  84         386  
406             # warn $ja;
407 504         1138 $ja = $manman . $ja;
408 504         3317 $ja =~ s{ \+\s*(\)|\z) }{$1}gx;
409             # warn $ja;
410 504     5   33412 my $result = eval qq{ use bignum; $ja };
  5     5   1636  
  5     4   13006  
  5     4   32  
  5     3   24  
  5     2   7  
  5     2   21  
  4     2   23  
  4     2   5  
  4     2   17  
  4     2   21  
  4     2   39  
  4     2   40  
  3     2   15  
  3     2   4  
  3     2   14  
  2     2   11  
  2     2   38  
  2     2   10  
  2     2   10  
  2     2   2  
  2     2   8  
  2     2   10  
  2     2   2  
  2     2   30  
  2     2   10  
  2     2   3  
  2     2   9  
  2     2   14  
  2     2   4  
  2     2   10  
  2     2   10  
  2     2   4  
  2     2   7  
  2     2   10  
  2     2   2  
  2     2   8  
  2     2   13  
  2     2   4  
  2     2   9  
  2     2   10  
  2     2   2  
  2     2   7  
  2     2   9  
  2     2   3  
  2     2   7  
  2     2   10  
  2     2   3  
  2     2   8  
  2     2   10  
  2     2   4  
  2     2   10  
  2     2   10  
  2     2   2  
  2     2   8  
  2     2   10  
  2     2   3  
  2     2   7  
  2     2   9  
  2     2   2  
  2     2   7  
  2     2   10  
  2     3   3  
  2     4   9  
  2     4   9  
  2     5   3  
  2     4   8  
  2     5   8  
  2     4   4  
  2     5   7  
  2     4   10  
  2     5   2  
  2     4   8  
  2     5   9  
  2     4   3  
  2     5   8  
  2     5   9  
  2     5   3  
  2     5   9  
  2     5   12  
  2     5   4  
  2     5   9  
  2     5   13  
  2     5   3  
  2     5   10  
  2     5   10  
  2     5   2  
  2     5   10  
  2     5   14  
  2     5   4  
  2     5   10  
  2     4   11  
  2     4   3  
  2     4   9  
  2     4   12  
  2     4   3  
  2     3   8  
  2     2   11  
  2     2   3  
  2     2   12  
  2     2   13  
  2     2   4  
  2     2   10  
  2     2   9  
  2     2   2  
  2     2   10  
  2     2   9  
  2     2   4  
  2     2   7  
  2     2   11  
  2     2   2  
  2     2   8  
  2     2   11  
  2     2   2  
  2     2   9  
  2     2   12  
  2     2   4  
  2     2   8  
  2     2   8  
  2     2   4  
  2     2   7  
  2     2   9  
  2     2   4  
  2     2   7  
  2     2   10  
  2     2   3  
  2     2   9  
  2     2   12  
  2     2   5  
  2     2   10  
  2     2   13  
  2     2   3  
  2     2   11  
  2     2   13  
  2     2   2  
  2     2   9  
  2     2   14  
  2     2   4  
  2     2   11  
  2     2   12  
  2     2   4  
  2     2   10  
  2     2   12  
  2     2   4  
  2     2   9  
  2     2   17  
  2     2   4  
  2     2   11  
  2     2   10  
  2     2   3  
  2     2   9  
  2     2   14  
  2     2   4  
  2     2   12  
  2     2   14  
  2     2   4  
  2     2   9  
  2     2   12  
  2     2   2  
  2     2   10  
  2     2   17  
  2     2   3  
  2     2   12  
  2     2   13  
  2     2   2  
  2     2   8  
  2     2   13  
  2     2   3  
  2     2   8  
  2         14  
  2         3  
  2         8  
  2         12  
  2         2  
  2         11  
  2         11  
  2         3  
  2         10  
  2         20  
  2         6  
  2         15  
  2         63  
  2         5  
  2         10  
  2         13  
  2         4  
  2         11  
  3         21  
  3         6  
  3         14  
  4         25  
  4         6  
  4         21  
  4         26  
  4         8  
  4         22  
  5         27  
  5         8  
  5         22  
  4         20  
  4         5  
  4         17  
  5         24  
  5         6  
  5         22  
  4         24  
  4         6  
  4         19  
  5         27  
  5         8  
  5         29  
  4         23  
  4         8  
  4         21  
  5         24  
  5         7  
  5         19  
  4         20  
  4         5  
  4         21  
  5         26  
  5         10  
  5         24  
  4         23  
  4         8  
  4         18  
  5         26  
  5         8  
  5         23  
  5         29  
  5         7  
  5         23  
  5         27  
  5         9  
  5         24  
  5         24  
  5         8  
  5         23  
  5         28  
  5         8  
  5         22  
  5         29  
  5         10  
  5         22  
  5         27  
  5         8  
  5         21  
  5         27  
  5         7  
  5         21  
  5         25  
  5         7  
  5         18  
  5         75  
  5         7  
  5         22  
  5         25  
  5         8  
  5         21  
  5         24  
  5         9  
  5         22  
  5         25  
  5         8  
  5         20  
  5         26  
  5         7  
  5         23  
  5         22  
  5         6  
  5         21  
  5         24  
  5         8  
  5         21  
  4         19  
  4         5  
  4         18  
  4         23  
  4         5  
  4         19  
  4         21  
  4         8  
  4         17  
  4         25  
  4         5  
  4         22  
  4         23  
  4         9  
  4         19  
  3         19  
  3         8  
  3         13  
  2         11  
  2         4  
  2         9  
  2         11  
  2         4  
  2         9  
  2         10  
  2         3  
  2         10  
  2         14  
  2         4  
  2         12  
  2         12  
  2         4  
  2         9  
  2         9  
  2         3  
  2         8  
  2         11  
  2         4  
  2         9  
  2         10  
  2         3  
  2         8  
  2         12  
  2         3  
  2         9  
  2         10  
  2         2  
  2         8  
  2         10  
  2         3  
  2         9  
  2         12  
  2         2  
  2         9  
  2         11  
  2         2  
  2         10  
  2         11  
  2         2  
  2         9  
  2         10  
  2         4  
  2         9  
  2         9  
  2         4  
  2         9  
  2         10  
  2         4  
  2         8  
  2         9  
  2         3  
  2         8  
  2         9  
  2         3  
  2         8  
  2         12  
  2         3  
  2         11  
  2         9  
  2         3  
  2         9  
  2         10  
  2         2  
  2         9  
  2         10  
  2         4  
  2         9  
  2         11  
  2         4  
  2         8  
  2         12  
  2         2  
  2         8  
  2         10  
  2         3  
  2         9  
  2         12  
  2         3  
  2         9  
  2         12  
  2         2  
  2         10  
  2         9  
  2         3  
  2         8  
  2         11  
  2         2  
  2         8  
  2         13  
  2         4  
  2         9  
  2         12  
  2         2  
  2         10  
  2         11  
  2         2  
  2         10  
  2         14  
  2         2  
  2         11  
  2         15  
  2         4  
  2         11  
  2         180  
  2         3  
  2         11  
  2         11  
  2         2  
  2         10  
  2         12  
  2         5  
  2         12  
  2         14  
  2         4  
  2         11  
  2         13  
  2         3  
  2         10  
  2         13  
  2         4  
  2         12  
  2         14  
  2         4  
  2         12  
  2         14  
  2         3  
  2         11  
  2         13  
  2         3  
  2         10  
  2         12  
  2         4  
  2         9  
  2         13  
  2         4  
  2         10  
  2         13  
  2         3  
  2         11  
  2         12  
  2         3  
  2         10  
  2         16  
  2         3  
  2         13  
  2         12  
  2         3  
  2         9  
  2         13  
  2         3  
  2         10  
  2         12  
  2         2  
  2         11  
  2         11  
  2         4  
  2         11  
  2         11  
  2         2  
  2         9  
  2         9  
  2         4  
  2         7  
  2         12  
  2         3  
  2         9  
  2         12  
  2         4  
  2         11  
  2         10  
  2         2  
  2         8  
  2         11  
  2         3  
  2         9  
  2         11  
  2         3  
  2         8  
  2         12  
  2         3  
  2         9  
  2         10  
  2         2  
  2         9  
  2         9  
  2         3  
  2         8  
  2         11  
  2         3  
  2         8  
  2         9  
  2         3  
  2         9  
  2         11  
  2         3  
  2         7  
  2         11  
  2         2  
  2         10  
  2         11  
  2         4  
  2         8  
  2         11  
  2         3  
  2         10  
  2         10  
  2         4  
  2         11  
  2         11  
  2         3  
  2         10  
  2         13  
  2         3  
  2         27  
411 504 50 33     2255 $@ and $opt->{debug} and warn "$ja =>\n $@";
412 504 50       1732 $opt->{debug} and warn qq{_ja2num("$ja") == $result};
413 504         10562 return qq($result);
414             }
415              
416             our %RE_TO_STRING_EXCP = (
417             Sanbyaku => 'san-byaku',
418             Roppyaku => 'ro-p-pyaku',
419             Happyaku => 'ha-p-pyaku',
420             Sanzen => 'san-zen',
421             Hassen => 'ha-s-sen',
422             );
423             our $RE_TO_STRING_EXCP = join("|", keys %RE_TO_STRING_EXCP);
424              
425             sub to_string{
426 4     4 1 2755 my ($str,$opt) = @_;
427 4   50     22 $opt ||= {};
428 4         12 $opt->{style} = "romaji";
429 4         6 delete $opt->{daiji};
430 4         6 delete $opt->{daiji_h};
431 4         12 my $ja = __PACKAGE__->new($str, $opt);
432 12         72 my @words =
433 4         11 map { s/($RE_TO_STRING_EXCP)/$RE_TO_STRING_EXCP{$1}/i; lc $_ }
  12         27  
434             ($ja->get_string =~ /([A-Z][a-z]*)/g);
435 4         30 return @words;
436             }
437              
438             1;
439             __END__