| File: | blib/lib/Geo/Address/Parser/Rules/CA.pm |
| Coverage: | 77.5% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package Geo::Address::Parser::Rules::CA; | |||||
| 2 | ||||||
| 3 | 1 1 1 | 208 1 14 | use strict; | |||
| 4 | 1 1 1 | 1 1 21 | use warnings; | |||
| 5 | 1 1 1 | 1 1 194 | use Exporter 'import'; | |||
| 6 | our @EXPORT_OK = qw(parse_address); | |||||
| 7 | ||||||
| 8 | our $VERSION = '0.07'; | |||||
| 9 | ||||||
| 10 | # Canadian postal code: A1A 1A1 (letters/digits with a space) | |||||
| 11 | my $postal_re = qr/\b([A-Z]\d[A-Z])\s*(\d[A-Z]\d)\b/i; | |||||
| 12 | ||||||
| 13 | # Canadian provinces (2-letter abbreviations) | |||||
| 14 | my $province_re = qr/\b(AB|BC|MB|NB|NL|NS|NT|NU|ON|PE|QC|SK|YT)\b/i; | |||||
| 15 | ||||||
| 16 | sub parse_address { | |||||
| 17 | 1 | 1 | my ($class, $text) = @_; | |||
| 18 | 1 | 1 | return unless defined $text; | |||
| 19 | ||||||
| 20 | 1 4 | 2 10 | my @parts = map { s/^\s+|\s+$//gr } split /,/, $text; | |||
| 21 | ||||||
| 22 | 1 | 1 | my ($name, $road, $city, $province, $postal); | |||
| 23 | ||||||
| 24 | # Check for province + postal code in last part | |||||
| 25 | 1 | 50 | if ($parts[-1] =~ /$province_re\s*$postal_re/) { | |||
| 26 | 1 | 2 | $province = uc($1); | |||
| 27 | 1 | 2 | $postal = uc("$2 $3"); | |||
| 28 | 1 | 1 | pop @parts; | |||
| 29 | } | |||||
| 30 | # If province only | |||||
| 31 | elsif ($parts[-1] =~ /^$province_re$/) { | |||||
| 32 | 0 | 0 | $province = uc($1); | |||
| 33 | 0 | 0 | pop @parts; | |||
| 34 | } | |||||
| 35 | ||||||
| 36 | 1 | 2 | $city = pop @parts if @parts; | |||
| 37 | 1 | 1 | $road = pop @parts if @parts; | |||
| 38 | 1 | 2 | $name = join(', ', @parts) if @parts; | |||
| 39 | ||||||
| 40 | return { | |||||
| 41 | 1 | 4 | name => $name, | |||
| 42 | road => $road, | |||||
| 43 | city => $city, | |||||
| 44 | region => $province, | |||||
| 45 | postcode => $postal, | |||||
| 46 | }; | |||||
| 47 | } | |||||
| 48 | ||||||
| 49 | 1; | |||||
| 50 | ||||||