File Coverage

blib/lib/Geo/StreetAddress/FR.pm
Criterion Covered Total %
statement 35 36 97.2
branch 5 6 83.3
condition n/a
subroutine 8 8 100.0
pod 1 1 100.0
total 49 51 96.0


line stmt bran cond sub pod time code
1             package Geo::StreetAddress::FR;
2              
3 4     4   97634 use warnings;
  4         10  
  4         129  
4 4     4   23 use strict;
  4         7  
  4         132  
5 4     4   21 use Carp;
  4         14  
  4         514  
6              
7 4     4   53 use base qw(Class::Accessor::Fast);
  4         15  
  4         4023  
8              
9             our $VERSION = '0.0.4';
10              
11             __PACKAGE__->mk_accessors( qw(adresse message) );
12              
13             our %extension_type_with_number = (
14             'etg' => 'etage',
15             'et' => 'etage',
16             'etage' => 'etage',
17             'ent' => 'entree',
18             'entree' => 'entree',
19             );
20              
21             our %extension_type = (
22             'res' => 'residence',
23             'resid' => 'residence',
24             'residence' => 'residence',
25             'bat' => 'batiment',
26             'batiment' => 'batiment',
27             'cour' => 'cours',
28             'cours' => 'cours',
29             'foyer' => 'foyer',
30             'ferme' => 'ferme',
31             'hlm' => 'immeuble',
32             'immeuble' => 'immeuble',
33             'immeubles' => 'immeuble',
34             'esc' => 'escalier',
35             'escalier' => 'escalier',
36             'porte' => 'porte',
37             'maison de retraite' => 'maison',
38             'Mais Retr' => 'maison',
39             );
40              
41             our %street_type = (
42             'all' => 'allee',
43             'allee' => 'allee',
44             'allees' => 'allee',
45             'av' => 'avenue',
46             'avenue' => 'avenue',
47             'bd' => 'boulevard',
48             'bld' => 'boulevard',
49             'bois' => 'bois',
50             'boulevard' => 'boulevard',
51             'bourg' => 'bourg',
52             'cami' => 'cami',
53             'camp militaire' => 'militaire',
54             'carrefour' => 'carrefour',
55             'cavee' => 'cavee',
56             'centre commercial' => 'commerce',
57             'ch' => 'chateau',
58             'chat' => 'chateau',
59             'chateau' => 'chateau',
60             'chaussee' => 'chaussee',
61             'chauss' => 'chaussee',
62             'che' => 'chemin',
63             'chem' => 'chemin',
64             'chemin' => 'chemin',
65             'cht' => 'chateau',
66             'cite' => 'cite',
67             'cloitre' => 'cloitre',
68             'clos' => 'clos',
69             'domaine' => 'domaine',
70             'esplanade' => 'esplanade',
71             'faubourg' => 'faubourg',
72             'fbg' => 'faubourg',
73             'fg' => 'fg',
74             'gde rue' => 'rue',
75             'gr' => 'rue',
76             'grand cour' => 'cours',
77             'grand rue' => 'rue',
78             'grande route' => 'route',
79             'grande rue' => 'rue',
80             'hameau' => 'hameau',
81             'imp' => 'impasse',
82             'impasse' => 'impasse',
83             'jardin' => 'jardin',
84             'jardins' => 'jardin',
85             'ldt' => 'lieu',
86             'lieu dit' => 'lieu',
87             'lot' => 'lotissement',
88             'lotiss' => 'lotissement',
89             'lotissement' => 'lotissement',
90             'mail' => 'mail',
91             'marche' => 'marche',
92             'montee' => 'montee',
93             'moulin' => 'moulin',
94             'parc' => 'parc',
95             'passage' => 'passage',
96             'passe' => 'passee',
97             'pavillon' => 'pavillon',
98             'petite route' => 'route',
99             'petite rue' => 'petite rue',
100             'pl' => 'place',
101             'place' => 'place',
102             'placette' => 'place',
103             'promenade' => 'promenade',
104             'quai' => 'quai',
105             'quartier' => 'quartier',
106             'quart' => 'quartier',
107             'rampe' => 'rampe',
108             'rdpt' => 'rondpoint',
109             'rond point' => 'rondpoint',
110             'route' => 'route',
111             'rte' => 'route',
112             'r' => 'rue',
113             'rue' => 'rue',
114             'ruelle' => 'rue',
115             'rues' => 'rue',
116             'sen' => 'sentier',
117             'sente' => 'sentier',
118             'sentier' => 'sentier',
119             'squ' => 'square',
120             'sq' => 'square',
121             'square' => 'square',
122             'tertre' => 'tertre',
123             'tour' => 'tour',
124             'traverse' => 'traverse',
125             'venelle' => 'venelle',
126             'vieille route' => 'route',
127             'villa' => 'village',
128             'village' => 'village',
129             'voie' => 'voie',
130             'zi' => 'zi',
131             'zone artisanale' => 'za',
132             'zone industrielle' => 'zi',
133             );
134              
135             our %_Street_Type_List = map { $_ => 1 } %street_type;
136             our %_Extension_Type_List = map { $_ => 1 } %extension_type;
137             our %_Extension_Type_Number_List
138             = map { $_ => 1 } %extension_type_with_number;
139              
140             my @comp = ( 'a' .. 'z' );
141             push @comp, 'bis', 'ter', 'quater', 'quinque', 'quinquies';
142              
143             our %Addr_Match = (
144             type => join( "|", keys %_Street_Type_List ),
145             extension => join( "|", keys %_Extension_Type_List ),
146             extension_number => join( "|", keys %_Extension_Type_Number_List ),
147             complement => join( "|", @comp ),
148             );
149              
150             {
151 4     4   23538 use re 'eval';
  4         8  
  4         2857  
152              
153             $Addr_Match{ adresse } = qr/
154             (?:
155             ([\d]+)(($Addr_Match{complement})?) (?{ $_{numero_voie} = $1; $_{complement} = $2 })
156             \s($Addr_Match{type}) (?{ $_{type_voie} = $^N })
157             (?:
158             \s(.*)\s(($Addr_Match{extension}).*) (?{$_{nom_voie} = $5; $_{extension} = $^N})
159             |
160             \s(.*) (?{ $_{nom_voie} = $^N })
161             |
162             \s(.*)\s(($Addr_Match{type}).*) (?{$_{nom_voie} = $5; $_{extension} = $^N})
163             )
164             )
165             |
166             (?:
167             ($Addr_Match{type})\b (?{ $_{type_voie} = $^N })
168             \s(.*) (?{ $_{nom_voie} = $^N })
169             )
170             |
171             (?:
172             (($Addr_Match{extension}|$Addr_Match{extension_number}).*) (?{$_{extension} = $^N})
173             (?:
174             \s(([\d]+)?) (?{ $_{numero_voie} = $^N})
175             (($Addr_Match{complement})?) (?{ $_{complement} = $^N})
176             \s($Addr_Match{type})\b (?{ $_{type_voie} = $^N })
177             \s(.*) (?{ $_{nom_voie} = $^N })
178             |
179             \s($Addr_Match{extension})\b (?{ $_{type_voie} = $^N })
180             \s(.*) (?{ $_{nom_voie} = $^N })
181             )
182             ) /ix;
183             }
184              
185             # warn $Addr_Match{adresse};
186              
187             =head1 NAME
188              
189             Geo::StreetAddress::FR - Perl extension for parsing French street addresses
190              
191              
192             =head1 SYNOPSIS
193              
194             use Geo::StreetAddress::FR;
195              
196             my $adresse = Geo::StreetAddress::FR->new;
197             $adresse->rue("15 grande rue");
198             $adresse->parse();
199             print $adresse->numero_voie. " " . $adresse->type_voie. " " .$adresse->nom_voie;
200              
201              
202             =head1 DESCRIPTION
203              
204             Geo::StreetAddress::FR is a street address parser for France.
205              
206             =head2 METHODS
207              
208             =head3 parse
209              
210             parse a street address, returning an address element.
211              
212             my $res = $adress->parse("bat C 13B route Bordeaux");
213             print $res->numero_voie; # will print 13
214             print $res->type_voie; # will print route
215             print $res->nom_voie; # will print Bordeaux
216             print $res->complement; # will print B
217             print $res->extension; # will print bat C
218              
219             return 'undef' if $adress->message is set, or if the adress can't be parsed.
220              
221             =cut
222              
223             sub parse {
224 17     17 1 32624 my $self = shift;
225              
226 17         34 local %_;
227              
228 17         51 $self->_adress_missing();
229              
230 17 100       156 return undef if defined $self->message();
231              
232 16 50       114 if ( $self->adresse =~ /$Addr_Match{adresse}/ios ) {
233 16         102 my %part = %_;
234 16         85 my $adresse = Geo::StreetAddress::FR::Element->new;
235 16         208 $adresse->nom_voie( $part{ 'nom_voie' } );
236 16         144 $adresse->numero_voie( $part{ 'numero_voie' } );
237 16         120 $adresse->type_voie( $part{ 'type_voie' } );
238 16         112 $adresse->complement( $part{ 'complement' } );
239 16         117 $adresse->extension( $part{ 'extension' } );
240 16         152 return $adresse;
241             }
242 0         0 return undef;
243             }
244              
245             sub _adress_missing {
246 17     17   24 my $self = shift;
247 17         56 $self->message( undef );
248 17 100       110 return if defined $self->adresse;
249 1         10 $self->message(
250             "You have to set an adress : \$mystreetobject->adresse(\"name of my adress\")"
251             );
252             }
253              
254             1;
255              
256             package Geo::StreetAddress::FR::Element;
257 4     4   25 use base qw(Class::Accessor::Fast);
  4         8  
  4         484  
258              
259             __PACKAGE__->mk_accessors(
260             qw(rue type_voie nom_voie complement numero_voie extension) );
261              
262             1;
263             __END__
264              
265             =head1 BUGS AND LIMITATIONS
266              
267             Please report any bugs or feature requests to
268             C<bug-geo-streetaddress-fr@rt.cpan.org>, or through the web interface at
269             L<http://rt.cpan.org>.
270              
271             =head1 SEE ALSO
272              
273             L<Geo::StreetAddress::US>
274              
275             Ideas and part of the code are coming from this module.
276              
277             =head1 AUTHOR
278              
279             franck cuny C<< <franck.cuny@gmail.com> >>
280              
281              
282             =head1 LICENCE AND COPYRIGHT
283              
284             Copyright (c) 2007, franck cuny C<< <franck.cuny@gmail.com> >>. All rights reserved.
285              
286             This module is free software; you can redistribute it and/or
287             modify it under the same terms as Perl itself. See L<perlartistic>.