繁体   English   中英

在序号字符串(第二,第八,第三,第一等)上分割地址字符串

[英]Splitting address strings on Sequential-Number strings (2nd, 8th, 3rd, first, etc..)

我的任务是标准化一些地址信息。 为了实现该目标,我将地址字符串分解为细微的值(我们的地址架构与Google的格式 非常相似)。

到目前为止的进展:
我正在使用PHP,目前正在发布Bldg,Suite,Room#等信息。
一切顺利,直到我遇到地板
在大多数情况下,楼层信息表示为“ Floor 10”“ Floor 86” 尼斯和容易。
对于那一点,我可以简单地将字符串打断成字符串( “ room”“ floor”等)。

问题:
但是后来我注意到我的测试数据集中有一些东西。 在某些情况下,代表楼层的方式更像是“ 2nd Floor”
这使我意识到,我需要为地面信息变化的整体转换做准备。
有诸如“ 3rd Floor”“ 22nd floor”“ 1ST FLOOR”之类的选项 那么,如何拼写出诸如“第十二层”这样的变体呢?
男人!! 这很快就会变得一团糟。

我的目标:
希望有人知道图书馆或已经解决了这个问题的东西。
在现实中,虽然,我会乐意有一些很好的建议/在一个人如何可以很好地处理拆分这种不同的标准(照顾,以避免误报,如“第三街”)的字符串指导。

首先,您需要详尽列出所有可能的输入格式,并确定要深入的内容。 如果您认为拼写出的变体为无效情况,则可以应用简单的正则表达式来捕获数字并检测标记(房间,地板...)

我将从阅读PHP的正则表达式开始。 例如:

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

其他有用的功能是preg_greppreg_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的数字,它宽泛地解释了格式不正确的构造,而不是抛出错误。 而且,它根本无法抵抗拼写错误。 例如:

  • 四十四秒= 82
  • 五十分之一= 2400
  • 第五十六秒九分之一= 67

如果输入很多,并且大多数输入格式正确,则因拼写错误而引发的错误并不是什么大问题,因为您可以手动更正问题条目的简短列表。 但是,根据您的应用程序,静默接受错误的输入可能是一个真正的问题。 在确定是否值得使转换代码更可靠时,只需考虑一下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM