File Coverage

blib/lib/Parse/JapanesePostalCode/Row.pm
Criterion Covered Total %
statement 189 193 97.9
branch 72 82 87.8
condition 11 15 73.3
subroutine 15 15 100.0
pod 2 9 22.2
total 289 314 92.0


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