File Coverage

blib/lib/Parse/JapanesePostalCode/Row.pm
Criterion Covered Total %
statement 190 194 97.9
branch 72 82 87.8
condition 10 15 66.6
subroutine 15 15 100.0
pod 2 9 22.2
total 289 315 91.7


line stmt bran cond sub pod time code
1             package Parse::JapanesePostalCode::Row;
2 16     16   78 use strict;
  16         28  
  16         352  
3 16     16   78 use warnings;
  16         23  
  16         340  
4 16     16   71 use utf8;
  16         23  
  16         70  
5              
6 16     16   13514 use Lingua::JA::Regular::Unicode qw/ katakana_h2z /;
  16         258442  
  16         1844  
7              
8             sub alnum_z2h {
9 997     997 0 1365 my $str = shift;
10 997         3080 $str = Lingua::JA::Regular::Unicode::alnum_z2h($str);
11 997         22391 $str =~ tr/~−/〜-/;
12 997         3587 $str;
13             }
14              
15             my @COLUMNS = qw/
16             region_id old_zip zip
17             pref_kana region_kana town_kana pref region town
18             is_multi_zip has_koaza_banchi has_chome is_multi_town
19             update_status update_reason
20             /;
21              
22             my @METHODS = (@COLUMNS, qw/
23             district district_kana city city_kana ward ward_kana
24             subtown_kana subtown
25             build build_kana floor
26             /);
27              
28             for my $name (@METHODS) {
29 2301     2301   31511 my $sub = sub { $_[0]->{columns}{$name} };
30 16     16   3019 no strict 'refs';
  16         31  
  16         46150  
31             *{$name} = $sub;
32             }
33              
34 75     75 0 585 sub columns { @COLUMNS }
35              
36 89     89 1 243 sub has_subtown { !! $_[0]->subtown }
37              
38             sub new {
39 75     75 1 696 my($class, %opts) = @_;
40              
41 75         138 my $columns = {};
42 75         172 for my $column (@COLUMNS) {
43 1125 100       4194 $columns->{$column} = delete $opts{$column} if defined $opts{$column};
44             }
45              
46 75         941 my $self = bless {
47             katakana_h2z => 1,
48             alnum_z2h => 1,
49             build_town => '',
50             build_town_kana => '',
51             %opts,
52             columns => $columns,
53             }, $class;
54              
55 75         277 $self->fix_region;
56 75         228 $self->fix_town;
57 75         236 $self->fix_build;
58 75 100       195 $self->fix_subtown unless $self->build;
59 75         226 $self->fix_kana_alnum;
60              
61 75         633 $self;
62             }
63              
64             sub fix_region {
65 75     75 0 133 my $self = shift;
66 75         179 my $columns = $self->{columns};
67              
68 75         211 $columns->{district} = undef;
69 75         138 $columns->{district_kana} = undef;
70 75         137 $columns->{city} = undef;
71 75         137 $columns->{city_kana} = undef;
72 75         120 $columns->{ward} = undef;
73 75         117 $columns->{ward_kana} = undef;
74              
75             # district
76 75         222 my($district, $town_village) = $self->region =~ /^(.+?郡)(.+[町村])$/;
77 75 100 66     339 if ($district && $town_village) {
78 25         77 my($district_kana, $town_village_kana) = $self->region_kana =~ /^((?:キタグンマ|.+?)グン)(.+)$/;
79              
80 25         61 $columns->{district} = $district;
81 25         42 $columns->{district_kana} = $district_kana;
82 25         48 $columns->{city} = $town_village;
83 25         69 $columns->{city_kana} = $town_village_kana;
84             } else {
85 50         122 my($city, $ward) = $self->region =~ /^(.+市)(.+区)$/;
86 50 100 66     253 if ($city && $ward) {
    100          
87 19         70 my($city_kana, $ward_kana) = $self->region_kana =~ /^((?:ヒロシマ|キタキュウシュウ|.+?)シ)(.+)$/;
88              
89 19         49 $columns->{city} = $city;
90 19         38 $columns->{city_kana} = $city_kana;
91 19         36 $columns->{ward} = $ward;
92 19         53 $columns->{ward_kana} = $ward_kana;
93             } elsif ($self->region =~ /区$/) {
94 9         26 $columns->{ward} = $self->region;
95 9         43 $columns->{ward_kana} = $self->region_kana;
96             } else {
97 22         47 $columns->{city} = $self->region;
98 22         71 $columns->{city_kana} = $self->region_kana;
99             }
100             }
101             }
102              
103             sub fix_town {
104 75     75 0 122 my $self = shift;
105 75         122 my $columns = $self->{columns};
106 75 100       618 if ($columns->{town} eq '以下に掲載がない場合') {
    100          
    100          
    100          
107 1         2 $columns->{town_kana} = undef;
108 1         2 $columns->{town} = undef;
109             } elsif ($columns->{town} =~ /^(.+)の次に番地がくる場合/) {
110 2         6 my $name = $1;
111 2 50 33     9 if ($columns->{city} eq $name || $columns->{city} =~ /郡\Q$name\E$/) {
112 2         3 $columns->{town_kana} = undef;
113 2         4 $columns->{town} = undef;
114             }
115             } elsif ($columns->{town} =~ s/(その他)$//) {
116 2         11 $columns->{town_kana} =~ s/\(ソノタ\)$//;
117             } elsif ($columns->{town} =~ /^(.+[町村])一円$/) {
118 2         5 my $name = $1;
119 2 50       5 if ($columns->{city} eq $name) {
120 2         4 $columns->{town_kana} = undef;
121 2         4 $columns->{town} = undef;
122             }
123             }
124              
125 75 100       558 $columns->{town} =~ s/[〜~]/〜/g if $columns->{town};
126             }
127              
128             sub fix_subtown {
129 67     67 0 96 my $self = shift;
130 67         106 my $columns = $self->{columns};
131 67 100       179 return unless $columns->{town};
132              
133 62         86 my @subtown;
134             my @subtown_kana;
135              
136             # chome
137 62 100       581 if ($columns->{town} =~ s/(([\d〜、]+)丁目)$//) {
    100          
    100          
138 5         19 my $num = alnum_z2h($1);
139              
140             my @nums = map {
141 8 100       35 if (/^(\d+)〜(\d+)$/) {
142 3         26 ($1..$2);
143             } else {
144 5         13 $_
145             }
146 5         21 } map { alnum_z2h($_) } split /、/, $1;
  8         14  
147              
148 5         12 @subtown = map { $_ . '丁目' } @nums;
  47         94  
149 5         10 @subtown_kana = map { $_ . 'チョウメ' } @nums;
  47         80  
150              
151 5         42 $columns->{town_kana} =~ s/\([\d\-、]+チョウメ\)$//;
152             }
153             # chiwari
154             elsif ($columns->{town} =~ /^[^\(]+地割/) {
155 5         39 my($prefix, $koaza) = $columns->{town} =~ /^(.+\d+地割)(?:((.+)))?$/;
156 5         30 my($prefix_kana, $koaza_kana) = $columns->{town_kana} =~ /^(.+\d+チワリ)(?:\((.+)\))?$/;
157              
158 5         30 my($aza, $chiwari) = $prefix =~ /^(.+?)第?(\d+地割.*)$/;
159 5         33 my($aza_kana, $chiwari_kana) = $prefix_kana =~ /^(.+?)(?:ダイ)?(\d+チワリ.*)$/;
160              
161 5 100       17 if ($chiwari =~ /〜/) {
162             my @tmp = map {
163 2 50       9 if (/\d+地割$/) {
  4         16  
164 4         7 my $str = $_;
165 4         37 $str =~ s/^\Q$aza\E//;
166 4         8 $str =~ s/^第//;
167 4         14 "第$str";
168             } else {
169 0         0 $_;
170             }
171             } split /〜/, $chiwari;
172 2         7 $chiwari = join '〜', @tmp;
173             }
174 5 100       20 if ($chiwari_kana =~ /-/) {
175             my @tmp = map {
176 2 50       8 if (/\d+チワリ$/) {
  4         16  
177 4         6 my $str = $_;
178 4         29 $str =~ s/^\Q$aza_kana\E//;
179 4         8 $str =~ s/^ダイ//;
180 4         13 "ダイ$str";
181             } else {
182 0         0 $_;
183             }
184             } split /-/, $chiwari_kana;
185 2         6 $chiwari_kana = join '-', @tmp;
186             }
187              
188             @subtown = map {
189 5 50       16 if (/\d+地割$/) {
  6         31  
190 6         9 my $str = $_;
191 6         81 $str =~ s/^\Q$aza\E//;
192 6         14 $str =~ s/^第//;
193 6         22 "第$str";
194             } else {
195 0         0 $_;
196             }
197             } split /、/, $chiwari;
198             @subtown_kana = map {
199 5 50       20 if (/\d+チワリ$/) {
  6         27  
200 6         7 my $str = $_;
201 6         53 $str =~ s/^\Q$aza_kana\E//;
202 6         15 $str =~ s/^ダイ//;
203 6         19 "ダイ$str";
204             } else {
205 0         0 $_;
206             }
207             } split /、/, $chiwari_kana;
208              
209 5 100       20 if ($koaza) {
210             @subtown = map {
211 2         5 my $str = $_;
  2         36  
212             map {
213 2         7 "$str $_";
  5         17  
214             } split /、/, $koaza;
215             } @subtown;
216             }
217 5 100       9 if ($koaza_kana) {
218             @subtown_kana = map {
219 2         3 my $str = $_;
  2         3  
220             map {
221 2         5 "$str $_";
  5         17  
222             } split /、/, $koaza_kana;
223             } @subtown_kana;
224             }
225              
226 5         10 $columns->{town} = $aza;
227 5         10 $columns->{town_kana} = $aza_kana;
228             }
229             # other
230             elsif ($columns->{town} =~ s/((.+?))$//) {
231 33         90 my $town = $1;
232 33         103 $town =~ s{「([^\」]+)」}{
233 6         17 my $str = $1;
234 6         24 $str =~ s/、/_____COMMNA_____/g;
235 6         33 "「${str}」";
236             }ge;
237             @subtown = map {
238 33         119 my $str = $_;
  102         132  
239 102         133 $str =~ s/_____COMMNA_____/、/g;
240 102         215 $str;
241             } split /、/, $town;
242 33 100       239 if ($columns->{town_kana} =~ s/\((.+?)\)$//) {
243 32         63 my $kana = $1;
244 32         83 $kana =~ s{<([^>]+)>}{
245 5         16 my $str = $1;
246 5         20 $str =~ s/、/_____COMMNA_____/g;
247 5         28 "<${str}>";
248             }ge;
249             @subtown_kana = map {
250 32         104 my $str = $_;
  94         114  
251 94         130 $str =~ s/_____COMMNA_____/,/g;
252 94         250 $str;
253             } split /、/, $kana;
254             }
255             }
256              
257 62 100       221 if (@subtown) {
258 43         90 $columns->{subtown} = \@subtown;
259 43         114 $columns->{subtown_kana} = \@subtown_kana;
260             }
261             }
262              
263             sub fix_build {
264 75     75 0 112 my $self = shift;
265 75         129 my $columns = $self->{columns};
266              
267 75 100       208 unless ($self->{build_town}) {
268 68 100 100     627 unless ($columns->{town} && $columns->{town} =~ /(.+?階.*?)$/) {
269 65         137 return;
270             }
271             }
272              
273 10         22 my $build_town = $self->{build_town};
274 10         28 my $build_town_kana = $self->{build_town_kana};
275              
276 10         34 $columns->{town} =~ s/(高層棟)//;
277 10         33 $columns->{town_kana} =~ s/\(コウソウトウ\)//;
278 10 100       171 if ($columns->{town} =~ s/(次のビルを除く)$//) {
    100          
279 1         5 $columns->{town_kana} =~ s/\(ツギノビルヲノゾク\)$//;
280             } elsif ($columns->{town} =~ /^\Q$build_town\E(.+)((.+))$/) {
281 8         28 my $floor = $2;
282 8         28 $columns->{build} = $1;
283 8 100       63 if ($floor =~ /(\d+)階/) {
284 6         19 $columns->{floor} = alnum_z2h($1);
285             }
286              
287 8         100 $columns->{town_kana} =~ /^\Q$build_town_kana\E(.+)\(.+$/;
288 8         34 $columns->{build_kana} = $1;
289              
290 8         19 $columns->{town} = $build_town;
291 8         27 $columns->{town_kana} = $build_town_kana;
292             }
293             }
294              
295             sub fix_kana_alnum {
296 75     75 0 106 my $self = shift;
297 75 100 66     235 return unless $self->{katakana_h2z} || $self->{alnum_z2h};
298 74         188 for my $name (qw/ pref_kana region_kana district_kana city_kana ward_kana town_kana build_kana pref region district city ward town build /) {
299 1036 100       2572 next unless defined $self->{columns}{$name};
300 682 100       2517 $self->{columns}{$name} = katakana_h2z($self->{columns}{$name}) if $self->{katakana_h2z};
301 682 100       14057 $self->{columns}{$name} = alnum_z2h($self->{columns}{$name}) if $self->{alnum_z2h};
302             }
303 74 100       252 if ($self->has_subtown) {
304 43         59 for my $i (0..(scalar(@{ $self->subtown }) - 1)) {
  43         86  
305 158 50       1352 $self->subtown->[$i] = katakana_h2z($self->subtown->[$i]) if $self->{katakana_h2z};
306 158 50       970 $self->subtown->[$i] = alnum_z2h($self->subtown->[$i]) if $self->{alnum_z2h};
307             }
308 43         67 for my $i (0..(scalar(@{ $self->subtown_kana }) - 1)) {
  43         101  
309 150 50       462 $self->subtown_kana->[$i] = katakana_h2z($self->subtown_kana->[$i]) if $self->{katakana_h2z};
310 150 50       623 $self->subtown_kana->[$i] = alnum_z2h($self->subtown_kana->[$i]) if $self->{alnum_z2h};
311             }
312             }
313             }
314              
315             1;
316             __END__