2

私はいくつかの住所情報を標準化する任務を負っています。その目標に向けて、アドレス文字列を細かい値に分割しています (アドレス スキーマはGoogle の形式に非常に似ています)。

これまでの進捗状況:
私は PHP を使用しており、現在、建物、スイート、部屋番号などの情報を分割しています。フロアズ
に出会うまでは順調だった。 ほとんどの場合、フロア情報は"Floor 10"または"Floor 86"として表されます。素敵で簡単。 その時点までのすべてについて、文字列の文字列を単純に分割できます("room""floor"など)。

問題:
しかし、その後、テスト データセットで何かに気づきました。フロアが「2階」のように表現される場合もあります。これにより、 FLOOR情報のバリエーションを大幅
に準備する必要があることに気付きました。「3階」「22階」「1」など の選択肢があります。では、 「Twelfth Floor」などのスペルアウトされたバリアントについてはどうでしょうか。 おとこ!!これはすぐに混乱する可能性があります。


の目標:この問題を既に解決しているライブラリまたは何かを誰かが知っていることを願っています。 ただし、実際には、このような多様な基準 ( "3rd St"などの誤検出を避けるように注意して) に基づいて文字列を分割する方法について、いくつかの良い提案/ガイダンスがあれば幸いです

4

2 に答える 2

0

まず、入力のすべての可能な形式の完全なリストを用意し、どの程度深くしたいかを決定する必要があります。スペルアウトされたバリアントを無効なケースと見なす場合は、単純な正規表現を適用して番号を取得し、トークン(部屋、床など)を検出できます。

于 2013-02-26T17:16:32.647 に答える
0

PHPで正規表現を読むことから始めます。例えば:

$floorarray = preg_split("/\sfloor\s/i", $floorstring)

その他の便利な関数は、、preg_grepなどpreg_matchです。

編集:より完全なソリューションを追加しました。

このソリューションは、床を説明する文字列を入力として受け取ります。次のようなさまざまな形式にすることができます。

  • 102階
  • 百二階
  • 百二階
  • 百二階
  • 102階
  • 102階

入力ファイルの例を見るまでは、これで十分だとあなたの投稿から推測しています。

<?php

$errorLog = 'error-log.txt'; // a file to catalog bad entries with bad floors

// These are a few example inputs
$addressArray = array('Fifty-second Floor', 'somefloor', '54th floor', '52qd floor',
  'forty forty second floor', 'five nineteen hundredth floor', 'floor fifty-sixth second ninth');

foreach ($addressArray as $id => $address) {
  $floor = parseFloor($id, $address);
  if ( empty($floor) ) {
    error_log('Entry '.$id.' is invalid: '.$address."\n", 3, $errorLog);
  } else {
    echo 'Entry '.$id.' is on floor '.$floor."\n";
  }
}

function parseFloor($id, $address)
{
  $floorString = implode(preg_split('/(^|\s)floor($|\s)/i', $address));

  if ( preg_match('/(^|^\s)(\d+)(st|nd|rd|th)*($|\s$)/i', $floorString, $matchArray) ) {
    // floorString contained a valid numerical floor
    $floor = $matchArray[2];
  } elseif ( ($floor = word2num($floorString)) != FALSE ) { // note assignment op not comparison
    // floorString contained a valid english ordinal for a floor
    ; // No need to do anything
  } else {
     // floorString did not contain a properly formed floor
    $floor = FALSE;
  }
  return $floor;
}

function word2num( $inputString )
{
  $cards = array('zero',
    'one',    'two',    'three',    'four',     'five',    'six',     'seven',     'eight',    'nine',     'ten',
    'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty');
  $cards[30] = 'thirty';  $cards[40] = 'forty';  $cards[50] = 'fifty'; $cards[60] = 'sixty';
  $cards[70] = 'seventy'; $cards[80] = 'eighty'; $cards[90] = 'ninety'; $cards[100] = 'hundred';
  $ords  = array('zeroth',
    'first',    'second',  'third',      'fourth',     'fifth',     'sixth',     'seventh',     'eighth',     'ninth',      'tenth',
    'eleventh', 'twelfth', 'thirteenth', 'fourteenth', 'fifteenth', 'sixteenth', 'seventeenth', 'eighteenth', 'nineteenth', 'twentieth');
  $ords[30] = 'thirtieth';  $ords[40] = 'fortieth';  $ords[50] = 'fiftieth';  $ords[60] =  'sixtieth';
  $ords[70] = 'seventieth'; $ords[80] = 'eightieth'; $ords[90] = 'ninetieth'; $ords[100] = 'hundredth';

  // break the string at any whitespace, dash, comma, or the word 'and'
  $words = preg_split( '/([\s-,](?!and\s)|\sand\s)/i', $inputString );

  $sum = 0;
  foreach ($words as $word) {
    $word = strtolower($word);
    $value = array_search($word, $ords); // try the ordinal words
    if (!$value) { $value = array_search($word, $cards); } // try the cardinal words
    if (!$value) {
      // if temp is still false, it's not a known number word, fail and exit
      return FALSE;
    }
    if ($value == 100) { $sum *= 100; }
    else { $sum += $value; }
  }

  return $sum;
}
?>

一般的なケースでは、単語を数字に解析するのは簡単ではありません。これについて議論している私が見つけた最高のスレッドはここにあります。数字を単語に変換するという逆問題ほど簡単ではありません。私のソリューションは、2000未満の数値に対してのみ機能し、エラーをスローするのではなく、形成が不十分な構造を自由に解釈します。また、スペルミスに対してはまったく回復力がありません。例えば:

  • 40秒=82
  • 519100分の1=2400
  • 56秒9=67

多くの入力があり、それらのほとんどが整形式である場合、問題のエントリの短いリストを手動で修正できるため、スペルミスでエラーをスローすることはそれほど大きな問題ではありません。ただし、アプリケーションによっては、不正な入力をサイレントに受け入れることが実際の問題になる可能性があります。変換コードをより堅牢にする価値があるかどうかを判断する際に考慮すべきことです。

于 2013-02-26T17:46:28.240 に答える