2017-05-03 10 views
0

解析する必要があるいくつかのフォーマットのデータが含まれているソースファイルがあります。他のデータと一致させる必要があるETLプロセスを作成しています。混在デリミタデータセットの解析

ほとんどのデータは都市、州(米国基準、多かれ少なかれ)の形式です。一部の都市は重い人口領域にまたがってグループ化され、複数の都市が結合されています。データのほとんどは、このようになります

(これは1呼び出す):

Elkhart, IN 

いくつかの場所には、複数の都市を持って、ダッシュで区切られた(呼び出し、この2):

Hickory-Lenoir-Morganton, NC 

それはまだありません都市が異なる州にあるときに複雑すぎる(この3と呼ぶ):

Steubenville, OH-Weirton, WV 

これはループのために私を投げた。それは理にかなっているが、それは以前のフォーマット(この4を呼び出し)フラッシュ:この例では

Kingsport, TN-Johnson City, TN-Bristol, VA-TN 

BristolVATNとの両方です。そして、これは(この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ステートメントの大きな山なしにこれを行う良い方法についての考えはありますか?

答えて

1

私は ' - 'と '、'で入力を分割し、配列の空の要素を削除します。 str_replaceの後にexplodeとarray_diff(、array())が必要です。 次に、州を特定します。リストを検索したり、都市が2つの大文字の名前を持つ傾向がないというプリンシパルで働いたりします。 今配列を処理します。それが都市であれば、名前を保存します。州の場合は、保存された都市に適用します。州の直後に都市がある場合は、都市のリストをクリアします。 例外を記入し、手動で別の入力に再フォーマットします。

これが役に立ちます。興味を持っている人のため

0

、私は@マイクからの回答を取り、これを思い付いた:

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プロセスを行っているので、スピードは最優先ではありません。私の特別なケースでは動作するエラー検出もありません。

関連する問題