æ¼¢æ°åé»å
ææã§å¿ è¦ã ã£ãã®ã§ï¼æ¼¢æ°åé»åç¨ã®ã¢ã¸ã¥ã¼ã«ãä½ã£ã¦ãã¾ããï¼æ¼¢æ°åãã¢ã©ãã¢æ°åã«å¤æãããï¼ã¢ã©ãã¢æ°åãæ¼¢æ°åã«å¤æãããã®ã§ãï¼ããããã§ãããã£ãããªï¼ã¨æã£ã¦ãããå¼¾ãããLingua-JA-Numbers-0.05 - Converts numeric values into their Japanese string equivalents and vice versa - metacpan.orgã¨ããã¢ã¸ã¥ã¼ã«ãä½ãããã®ã§ï¼ãã£ãããèµå ¥ãã«ãªãã¾ããï¼(T^T) ãã®ã¾ã¾æ¨ã¦ã¦ãã¾ãã®ããã£ãããªãã®ã§ï¼ããã«ãããã¾ãï¼
æ¼¢æ°åã®è¡¨ç¾ã¯ï¼ä¸ äº ä¸ å äº å ä¸ å « ä¹ å ç¾ å ä¸ å å 京 å ç¦¾äº ç©£ æº æ¾ æ£ è¼ æ¥µ ææ²³æ² é¿å§ç¥ é£ç±å¤ ä¸å¯æè° ç¡é大æ°ã使ã£ã¦ãã¾ãï¼ä¸ãã極ã¾ã§ã¯ä¸é²(10^4)ï¼ææ²³æ²ããç¡é大æ°ã¾ã§ã¯ä¸ä¸é²(10^8)ã§ãï¼
package JANumbers; use base qw(Exporter); use encoding 'shiftjis'; use bignum; use strict; our @EXPORT = qw(arabic2chinese chinese2arabic); ## æ§é å®ç¾© # my ($tag1, $tag2, $tag3, $digit, @num1, @num2, @num3, @num4, %table); $tag1 = q{(?:å|ç¾|å|\b)}; $tag2 = q{(?:è¼|æ£|æ¾|æº|ç©£|禾äº|å|京|å |å|ä¸|\b)}; $tag3 = q{(?:ç¡é大æ°|ä¸å¯æè°|é£ç±å¤|é¿å§ç¥|ææ²³æ²|極|\b)}; $digit = q{(?:ä¸|äº|ä¸|å|äº|å |ä¸|å «|ä¹)}; @num1 = qw(ä¸ äº ä¸ å äº å ä¸ å « ä¹); @num2 = qw(å ç¾ å); @num3 = qw(ä¸ å å 京 å äºç¦¾ ç©£ æº æ¾ æ£ è¼); # 禾äºãéã«ãã¦ãã @num4 = qw(極 ææ²³æ² é¿å§ç¥ é£ç±å¤ ä¸å¯æè° ç¡é大æ°); unshift @num1, ''; unshift @num2, ''; unshift @num3, ''; %table = ( 'ä¸' => 1, 'äº' => 2, 'ä¸' => 3, 'å' => 4, 'äº' => 5, 'å ' => 6, 'ä¸' => 7, 'å «' => 8, 'ä¹' => 9, 'å' => 10, 'ç¾' => 10**2, 'å' => 10**3, 'ä¸' => 10**4, 'å' => 10**8, 'å ' => 10**12, '京' => 10**16, 'å' => 10**20, '禾äº' => 10**24, 'ç©£' => 10**28, 'æº' => 10**32, 'æ¾' => 10**36, 'æ£' => 10**40, 'è¼' => 10**44, '極' => 10**48, 'ææ²³æ²' => 10**56, 'é¿å§ç¥' => 10**64, 'é£ç±å¤' => 10**72, 'ä¸å¯æè°' => 10**80, 'ç¡é大æ°' => 10**88, ); ## _fourchar($) # ä¸é²ã®æ°åå¦ç # æåå $str ã渡ãã¨æ°åãè¿ã # sub _fourchar($) { my $str = shift; my $ret; while ($str =~ /($digit)?($tag1)/g){ my $block = $table{$1}; # äºåã ã£ãã äº my $unit = $table{$2}; # äºåã ã£ãã å ## æ¡è¡¨è¨ãããã®ã«æ¼¢æ°åããªã # 1 x 10^n ã®æ # $block = 1 if (!$block && $unit); ## æ¼¢æ°åãããã®ã«æ¡è¡¨è¨ããªã # n x 1 ã®æ # $unit = 1 if ($block && !$unit); $ret += $block * $unit; } return $ret; } ## _eightchar($) # ä¸ä¸é²ã®æ°åå¦ç # æåå $str ã渡ãã¨æ°åãè¿ã # sub _eightchar($) { my $str = shift; my $ret; while ($str =~ /([^$tag2]+)($tag2)/g){ my $block = _fourchar($1); my $unit = $table{$2} || 1; $ret += $block * $unit; } return $ret; } ## chinese2arabic($) # æ¼¢æ°åãã¢ã©ãã¢æ°åã«å¤æ # æåå $str ã渡ãã¨æ°åãè¿ã # sub chinese2arabic($) { my $str = shift; my $ret; while ($str =~ /([^$tag3]+)($tag3)/g){ my $block = _eightchar($1); my $unit = $table{$2} || 1; $ret += $block * $unit; } return $ret; } ## _expo($$) # æ°å $num ã¨æ¡ $pos ã渡ãã¨æååãè¿ã # sub _expo($$) { my $num = shift; my $pos = shift; my $ret; return '' if ($num == 0); return 'ä¸' if (($num == 1) && ($pos == 0)); return $num2[$pos] if (($num == 1) && ($pos > 0)); return $num2[$pos] . $num1[$num]; } ## _fourdigit($) # ä¸é²ã®æ¼¢æ°åå¦ç # æ°å $num ã渡ãã¨æååãè¿ã # sub _fourdigit($) { my $num = shift; my ($pos1, $ret); map{ my $pos2; $ret .= $num3[$pos1++]; s/(\d)/_expo($1, $pos2++)/eg; $ret .= $_; }(reverse($num) =~ /\d{1,4}/g); return $ret = reverse($ret); } ## _eightdigit($) # ä¸ä¸é²ã®æ¼¢æ°åå¦ç # æ°å $num ã渡ãã¨æååãè¿ã # sub _eightdigit($) { my $num = shift; my ($pos1, $ret); map{ $ret = _fourdigit(reverse($_)) . $num4[$pos1++] . $ret; }(reverse($num) =~ /\d{1,8}/g); return $ret; } ## arabic2chinese($) # ã¢ã©ãã¢æ°åãæ¼¢æ°åã«å¤æ # æ°å $num ã渡ãã¨æååãè¿ã sub arabic2chinese($) { my $num = shift; my ($fourdigit, $eightdigit); $num =~ /(\d{0,48}?)$/; return _eightdigit($`) . _fourdigit($1); } 1;
解説ãããããªï¼ã¨æãã¤ã¤ï¼ãã®ããã°ãè¦ã¦ãã²ã¨ã¯ãããªã«ããªãã ããããï¼æ¾ç½®ï¼ãï¼WinXP + Activestateä¸ã§ä½ã£ã¦ããã®ã§ï¼æåã³ã¼ãã«shiftjisãæå®ãã¦ãã¾ãï¼