2

配列に分解する必要があるアドレスのリストがあります。

そこで、explodeを使用して各行を配列に分割することを考え始めました。これは、次のようなアドレスで正常に機能します。

アドウェル-オックスフォードシャー51.68N01.00WSU6999

しかし、私がこのようなアドレスを持っていた場合:

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

2番目のアドレスの出力は次のようになります。

0=>アファン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

そのために正規表現は必要ないと思います。単純な爆発呼び出しで十分です。

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

より進んだ方法

$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

構文をより明確にする必要があります。これらの2つの例から、次のことが機能するはずです。

  • ' - 'セパレータとして使用して、2つのコンポーネントに分割します。最初のコンポーネントはそのままにしておくことができ、残りはさらに処理する必要があります。
  • 残りの部分から、最後の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+)

おそらく最も柔軟です。iveは、空白のほとんどをオプションにしました。ただし、\ s +は、フリーテキストの一種の区切り文字として使用されるためです。

于 2012-05-16T13:47:35.540 に答える
0

私はかなり前からアドレス解析などに取り組んできましたが、残念ながら、すべての拠点をカバーするソリューションはありません。したがって、決定する必要があるのは、すべてのアドレスに共通するものです。私には、これは右側のもののようです。だから私は最初にそれらを解析します。スペースで爆発して最後の3つのアイテムをつかむことができるようです(ポップx 3またはスライス作品)。次に、再結合(参加)して正規表現します。

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

これにより、2つの文字列のバッチが得られます。1つは最初のもので、2つ目は残っているものです。次に、括弧内に何かがあるかどうかを確認し、それに応じてそれらを解析する必要があります。

残念ながら、私は主に米国ベースのアドレス文字列/ブロックを扱っているため、あなたのアドレス形式に完全には精通していません。ただし、共通のアイテムを最後から削除した後、残りの文字列には、市/州/県の部分を簡単に識別できるようにする必要があります。いずれにせよ、最終結果が可能な限り正確であることを保証するために、正規表現とロジックのガントレットが必要です。基本的に、データが入ってくるときにそのフォーマットに基づいて取得するデータのパスを設計します。

幸運を!

于 2012-05-16T13:55:23.787 に答える