2

我有一个需要分解为数组的地址列表。

所以我开始考虑使用explode 将每一行分解成一个数组。在这样的地址上可以正常工作:

阿德威尔 - 牛津郡 51.68N 01.00W SU6999

但如果我有这样的地址:

Afan - Castell-nedd Phort Talbot (Neath Port Talbot) 51.63N 03.74W SS794938

这会导致问题。

我一直在尝试使用 preg_match 但无法使表达式起作用,因此我最终得到:

0 => 阿德威尔 1 => 牛津郡 2 => 51.68N 3 => 01.00W 4 => SU6999

第二个地址的输出应该是

0=> Afan 1=> Castell-nedd Phort Talbot (Neath Port Talbot) 2=> 51.63N 3=> 03.74W 4=> SS794938

有没有人看到用正则表达式实现这一目标的好方法?

4

5 回答 5

2
<?php
// Solution.
function parseAddress($address)
{
    $matches = NULL; 
    preg_match('/([^-]*) - ([^\d]*) (\d\d\.\d\dN) (\d\d\.\d\dW) (.*)/',
               $address, $matches);
    return array_slice($matches, 1);
}

// Test case 1.
$parsed = parseAddress('Adwell - Oxfordshire 51.68N 01.00W SU6999');
var_dump($parsed);

// Test case 2.
$parsed = parseAddress('Afan - Castell-nedd Phort Talbot (Neath Port Talbot) ' .
                       '51.63N 03.74W SS794938');
var_dump($parsed);
?>

输出:

array(5) {
  [0]=>
  string(6) "Adwell"
  [1]=>
  string(11) "Oxfordshire"
  [2]=>
  string(6) "51.68N"
  [3]=>
  string(6) "01.00W"
  [4]=>
  string(6) "SU6999"
}
array(5) {
  [0]=>
  string(4) "Afan"
  [1]=>
  string(45) "Castell-nedd Phort Talbot (Neath Port Talbot)"
  [2]=>
  string(6) "51.63N"
  [3]=>
  string(6) "03.74W"
  [4]=>
  string(8) "SS794938"
}
于 2012-05-16T13:55:02.190 回答
1

I think you dont need regex for that. Just simple explode call is enough.

explode(' ', "Adwell - Oxfordshire 51.68N 01.00W SU6999")

More advance way,

$str = "Afan - Castell-nedd Phort Talbot (Neath Port Talbot) 51.63N 03.74W SS794938";
$parts = array_filter(explode(' ', $str));
$ss = array_pop($parts);
$w = array_pop($parts);
$n = array_pop($parts);
$name = array_shift($parts);
$hash = array_shift($parts);
$result = array($name, implode($parts, ' '), $n, $w, $ss);
print_r($result);
于 2012-05-16T13:44:52.400 回答
1

您需要更好地消除语法歧义。从这两个示例中,我的猜测是以下应该有效:

  • 分成两部分,' - '用作分隔符。第一个组件可以保持原样,其余的需要进一步处理。
  • 从其余部分中取出最后 3 个以空格分隔的部分,其余部分保持原样。

所以试试这个:

/^(.*?)\s-\s(.*)\s+(\S+)\s+(\S+)\s+(\S+)$/

如果没有对预期输入格式的更正式的描述,没有人可以给你一个决定性的答案。

于 2012-05-16T13:51:57.693 回答
0
(.*)\s+-\s*(.*)\s+(\d+\.\d+N)\s*(\d+\.\d+W)\s*(SS\d+)

可能是最灵活的。我将大部分空白设为可选,除了您看到 \s+ 的位置,因为它使用它作为自由文本的一种分隔符

于 2012-05-16T13:47:35.540 回答
0

我从事地址解析等工作已经有一段时间了,不幸的是,没有涵盖所有基础的解决方案。因此,您需要确定的是所有地址中的共同点。对我来说,这似乎是右边的东西。所以我会先把它们解析出来。似乎您可以按空间爆炸并抓住最后 3 件物品(pop x 3 或 slice 作品)。然后重新组合(加入)并对其进行正则表达式。

/([a-z]+)\s-\s([a-z\-)\s\(\)]+)/i

这会给你两批字符串。一个是第一个东西,第二个是剩下的东西。然后,您需要检查括号中是否有任何内容并相应地解析出这些内容。

不幸的是,我并不完全熟悉您的地址格式,因为我主要处理基于美国的地址字符串/块。但是,从末尾删除常见项目后,剩余的字符串应该可以轻松识别其城市/州/省部分。无论哪种方式,您都需要一套正则表达式和逻辑来确保最终结果尽可能准确。本质上,您根据数据的格式为数据设计一条路径。

祝你好运!

于 2012-05-16T13:55:23.787 回答