我有一个源文件,其中包含一些我需要解析的格式的数据。我正在编写一个必须与其他数据匹配的ETL过程。
大多数数据的格式为城市,州(美国标准,或多或少)。一些城市分布在人口较多的地区,多个城市相结合。
大部分数据都是这样的(称之为1):
Elkhart, IN
有些地方有多个城市,用破折号分隔(称之为2):
Hickory-Lenoir-Morganton, NC
当城市处于不同的状态时,它仍然不会太复杂(称之为3):
Steubenville, OH-Weirton, WV
这个人把我扔了一圈;它有意义,但它刷新以前的格式(称之为4):
Kingsport, TN-Johnson City, TN-Bristol, VA-TN
在该示例中,Bristol
和VA
同时包含TN
。然后是这个(称之为5):
Mayagüez/Aguadilla-Ponce, PR
我可以用破折号替换斜线并处理与前一个示例相同的斜杠。这包含一个变音符号,我的其余数据都是不含变音符号的。我很好地剥离了变音符号,这在PHP中似乎有些简单。
然后是我的最后一个例子(称之为6):
Scranton--Wilkes-Barre--Hazleton, PA
城市名称包含破折号,因此城市名称之间的分隔符是双破折号。
我想要产生的是,给定上述任何一个示例和几百个遵循相同格式的其他行,每个都有一个[[city, state],...]
数组,因此我可以将它们转换为SQL。例如,解析4将产生:
[
['Kingsport', 'TN'],
['Johnson City', 'TN'],
['Bristol', 'VA'],
['Bristol', 'TN']
]
我正在使用标准的PHP安装,我有preg_match
等等,但没有PECL库。订单并不重要。
如果没有大量的if-then陈述,有什么好的方法可以做到这一点吗?
答案 0 :(得分:1)
我会用'-'s和'分隔输入,然后删除数组中的空元素。 str_replace后跟explode和array_diff(,array())应该做的伎俩。 然后确定国家 - 搜索列表或处理校长,城市不具有2个大写字母名称。 现在通过数组工作。如果是城市,请保存名称,如果是州,则将其应用于已保存的城市。当您在州之后立即获得城市时,清除城市列表。 注意任何异常并手动重新格式化为不同的输入。
希望这有帮助。
答案 1 :(得分:0)
对于任何有兴趣的人,我都从@mike那里得到了答案并提出了这个问题:
function SplitLine($line) {
// This is over-simplified, just to cover the given case.
$line = str_replace('ü', 'u', $line);
// Cover case 6.
$delimiter = '-';
if (false !== strpos($line, '--'))
$delimiter = '--';
$line = str_replace('/', $delimiter, $line);
// Case 5 looks like case 2 now.
$parts = explode($delimiter, $line);
$table = array_map(function($part) { return array_map('trim', explode(',', $part)); }, $parts);
// At this point, table contains a grid with missing values.
for ($i = 0; $i < count($table); $i++) {
$row = $table[$i];
// Trivial case (case 1 and 3), go on.
if (2 == count($row))
continue;
if (preg_match('/^[A-Z]{2}$/', $row[0])) {
// Missing city; seek backwards.
$find = $i;
while (2 != count($table[$find]))
$find--;
$table[$i] = [$table[$find][0], $row[0]];
} else {
// Missing state; seek forwards.
$find = $i;
while (2 != count($table[$find]))
$find++;
$table[$i][] = $table[$find][1];
}
}
return $table;
}
它不漂亮而且速度很慢。它确实涵盖了我的所有情况,因为我正在进行ETL过程,速度并不是最重要的。还没有错误检测,这在我的特定情况下有效。