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

4

5 回答 5

7

我建议您不要尝试在单个正则表达式中完成所有这些操作,因为很难验证其正确性。

首先,我会在逗号处分开。逗号后面的内容是 $town,如果没有逗号,则整个字符串都是 $town。

然后我会检查是否有任何批次信息并将其从字符串中提取出来。

然后我会寻找街道/大道号码和名称。

分而治之:)

于 2010-02-18T12:26:42.270 回答
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 = [
          {
            '很多' => undef,
            '数字' => '123',
            '街道' => '任何街道',
            '城镇' => '我的城镇'
          },
          {
            '批次' => '批次 4',
            '数字' => undef,
            '街道' => '另一条路',
            '城镇' => '那个城镇'
          },
          {
            '批次' => '批次 2',
            '数字' => '96',
            '街道' => '另一条路',
            '城镇' => '她的城镇'
          },
          {
            '很多' => undef,
            '数字' => undef,
            'street' => undef,
            '城镇' => '你的城镇'
          },
          {
            '很多' => undef,
            '数字' => undef,
            '街道' => '街道',
            '城镇' => '城镇'
          }
        ];
于 2010-02-18T13:48:12.260 回答
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')
于 2010-02-18T12:36:10.003 回答
0

我无法匹配最后一个,但对于前 3 个,您可以使用如下内容:

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

这是测试正则表达式:

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

您可以在 regexbuddy 中使用它来测试:link

于 2010-02-18T12:41:26.817 回答
0

Geo::StreetAddress::US 适用于简单地址,但在较难的示例中可能会丢失上下文。它将解析街道名称,直到找到郊区。所以对于“46 7th St. Johns Park”,“St.” 消耗太快,街道类型被错误地分配给“公园”,“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。它可以识别诸如“The Parade”、nth Street 等成语,以及诸如“46 Broad Street #12”之类的子物业地址等等。

于 2015-03-04T01:52:07.983 回答