2010-02-18 3 views
1

Я должен создать цикл, и с регулярным выражением заполнения любой из 4-х переменныхАнализировать адрес с регулярным выражением

$address, $street, $town, $lot 

петля будет подаваться строка, которая может иметь данные в нем как ниже линии

  • '123 any street, mytown' или
  • 'Lot 4 another road, thattown' или
  • 'Lot 2 96 other road, her town' или
  • 'this ave, this town' или
  • 'yourtown'

, поскольку ничего после запятой является $town я думал

(.*), (.*) 

тогда первый захват может быть проверен с (Lot \d*) (.*), (.*) если первый захват начинается с номером , то его адрес (если слово с пробелом $street) если одно слово, то его просто $town

+0

См. Также http://stackoverflow.com/questions/642602/regular-expression- для-парсинга-почтовых адресов http://stackoverflow.com/questions/16413/parse-usable-street-address-city-state-zip-from-a-string и т. д. –

ответ

7

Взгляните на Geo::StreetAddress::US, если эти адреса в США.

Даже если это не так, источник этого модуля должен дать вам представление о том, что участвует в разборе адресов свободной формы.

Вот скрипт, который обрабатывает адреса, которые вы размещены (обновленные, ранее версии объединены много и число в одну строку):

#!/usr/bin/perl 

use strict; use warnings; 

local $/ = ""; 

my @addresses; 

while (my $address = <DATA>) { 
    chomp $address; 
    $address =~ s/\s+/ /g; 
    my (%address, $rest); 
    ($address{town}, $rest) = map { scalar reverse } 
         split(/ ?, ?/, reverse($address), 2); 

    { 
     no warnings 'uninitialized'; 
     @address{qw(lot number street)} = 
      $rest =~ /^(?:(Lot [0-9]))?(?:([0-9]+))?(.+)\z/; 
    } 
    push @addresses, \%address; 
} 

use Data::Dumper; 
print Dumper \@addresses; 

__DATA__ 
123 any street, 
mytown 

Lot 4 another road, 
thattown 

Lot 2 96 other road, 
her town 

yourtown 

street, 
town 

Выход:

$VAR1 = [ 
      { 
      'lot' => undef, 
      'number' => '123', 
      'street' => 'any street', 
      'town' => 'mytown' 
      }, 
      { 
      'lot' => 'Lot 4', 
      'number' => undef, 
      'street' => 'another road', 
      'town' => 'thattown' 
      }, 
      { 
      'lot' => 'Lot 2', 
      'number' => '96', 
      'street' => 'other road', 
      'town' => 'her town' 
      }, 
      { 
      'lot' => undef, 
      'number' => undef, 
      'street' => undef, 
      'town' => 'yourtown' 
      }, 
      { 
      'lot' => undef, 
      'number' => undef, 
      'street' => 'street', 
      'town' => 'town' 
      } 
     ];
7

Я предлагаю вам не пытаться делать все это в одном регулярном выражении, так как будет трудно проверить его правильность.

Во-первых, я бы разделился на запятую. Все, что приходит после запятой, это город $, и если нет запятой, вся строка - это $ city.

Тогда я бы проверить, есть ли какая-либо информация о партии и извлечь ее из строки.

Тогда я бы посмотрел номер и имя улицы/авеню.

Разделяй и властвуй :)

1

Это должно разделить на 3 части - как вы отличаете адрес/улицу?

(Lot \d*)? ?([^,]*,)? ?(.*) 

здесь пробой для примеров

('', '123 any street,', 'mytown') 
('Lot 4', 'another road,', 'thattown') 
('Lot 2', '96 other road,', 'her town') 
('', 'this ave,', 'this town') 
('', '', 'yourtown') 

Если я правильно понимаю, это один отделяет адрес/улицу, а

(Lot \d*)? ?(\d*) ?([^,]*,)? ?(.*) 

('', '123', 'any street,', 'mytown') 
('Lot 4', '', 'another road,', 'thattown') 
('Lot 2', '96', 'other road,', 'her town') 
('', '', 'this ave,', 'this town') 
('', '', '', 'yourtown') 
+0

Номера домов не так просты: они могут после них имейте буквы (или даже IIRC перед ними) или 1/2 и т. д. – ysth

+0

@ysth, Мы тестируем случаи, чтобы покрыть их тогда. Расширение регулярного выражения не так сложно - угадайте требования. –

0

я не могу соответствовать последней но для первых 3-х вы можете использовать примерно следующее:

if (preg_match('/(?:Lot (\d*)|)(?: |)(?:(\d*)|) (.*), (.*)/m', $subject, $regs)) { 
    $result = $regs[1]; 
} else { 
    $result = ""; 
} 

это тестирование регулярное выражение:

(?:Lot (\d*)|)(?: |)(?:(\d*)|) (.*), (.*) 

Вы можете использовать это в RegexBuddy для теста: link

0

Geo :: StreetAddress :: США отлично подходят для простых адресов, но это может потерять контекст на более сложных примерах. Он будет разбирать названия улиц до тех пор, пока не найдет пригород. Так, с «46 7-м парком Сент-Джонс», «Св. расходуется слишком рано, тип улицы неправильно присваивается «Парку», а «CA» становится пригородом.

2 Smith St Suburb NJ 12345    2 Smith   St Suburb   NJ 12345 
25 MIRROR LAKE DR LITTLE EGG HARBOR 25 MIRROR LAKE DR Hbr NJ      0 
74B Old Bohema Rd N, St. Johns Park 74 B Old Bohema Rd St Johns Park CA 95472 
74 Mt Baw Baw Rd Suite C Some Park C 74 Mt Baw Baw Rd S Park CA      0 
74 Old Bohema Rd Bldg A Some Park CA 74 Old Bohema Rd B Park CA      0 
74 Old Bohema Rd Rm 123A Some Park C 74 Old Bohema Rd R Park CA      0 
Lot 74 Old Bohema Rd Some Park CA 95 0 Old Bohema Rd S Park CA      0 
22 Glen Alpine Way Some Park CA 9547 22 Glen Alpine Way Park CA      0 
4/6 Bohema Rd, St. Johns Park CA 954 4 6 Bohema  Rd St Johns Park CA 95472 
46 The Parade, St. Johns Park CA 954 46 The     Parade     0 
46 7th St. Johns Park CA 95472   46 7th St Johns Park CA      0 
46 B Avenue Johns Park CA 95472  46 B Avenue Johns Park CA      0 
46 Avenue C Johns Park CA 95472  46 Avenue C Johns Park CA      0 
46 Broadway Johns Park CA 95472  46 Broadway Johns Park CA      0 
46 State Route 19 Johns Park CA 9547 46 State Route 19 Park CA      0 
46 John F Kennedy Drive Johns Park C 46 John F Kennedy Park CA      0 
PO Box 213 Somewhere IO 1234   0 Somewhere   IO      0 
1 BEACH DR SE # 2410 ST PETERSBURG F 1 BEACH DR SE # 2 St PETERSBURG  FL 33701 
# 123 12 BEACH DR SE ST PETERSBURG F 12 BEACH DR SE  St PETERSBURG  FL 33701 
46 Broad Street #12 Suburb CA 95472 46 Broad   St       0 

Я разработал модуль Perl, который может идентифицировать многие из этих более сложных моделей https://metacpan.org/release/Lingua-EN-AddressParse. Он распознает такие идиомы, как «Парад», nth Street, адреса вспомогательных свойств, такие как «46 Broad Street № 12» и многие другие.

Смежные вопросы