Нормализовать состояние данных

У меня есть устаревшая форма, которая собирала данные о состоянии от пользователей. Он собирал данные в текстовом поле, поэтому пользователь мог вводить все, что хотел. Некоторые примеры входных данных включают в себя:

'plattsburgh, new york'
'California'
'Central Valley,Ca/ Ptld, Oregon'
'Bay area,CA'
'new port richey florida'
'HAMPTON ROADS AREA'
'DC Metro area'
'Pennsylvania, Colorado, New York, Maryland Federal Facilities, Military Facilities,'

Я хочу программно нормализовать эти данные с помощью PHP, чтобы вытащить только состояния и удалить все остальное. Поэтому, учитывая приведенные выше примеры, я хотел бы преобразовать их как таковые:

'plattsburgh, new york' => 'NY'
'California' => 'CA'
'Central Valley,Ca/ Ptld, Oregon' => 'OR'
'Bay area,CA' => 'CA'
'new port richey florida' => 'CA'
'HAMPTON ROADS AREA' => ''
'DC Metro area' => 'DC'
'Pennsylvania, Colorado, New York, Maryland Federal Facilities, Military Facilities,' => 'PA,CO,NY,MD'

Есть ли хороший, чистый способ сделать это?

1

Решение

Что вы делаете, это берете введенные пользователем данные и пытаетесь их надежно отформатировать. Как я покажу в моем примере, это, как правило, плохо, поскольку введенные пользователем данные могут быть полны несоответствий. Я бы посоветовал улучшить сбор данных (заставьте пользователя заполнить красиво оформленную форму с отдельными полями для каждой части своего адреса или сделайте так, чтобы они выбирали состояние из списка состояний). Но сейчас мы посмотрим, как лучше отформатировать ваши данные, насколько это возможно.

Самый простой способ добиться того, что вы хотите сделать, это сгенерировать «карту» данных и использовать карту для форматирования ваших данных.

Например, я создал две карты, как вы можете видеть ниже. Первый, это карта «имя» к «a2». Массив содержит имена состояний (с большой буквы) в качестве индексов и состояние a2 в качестве значения.

$nameToA2Map = array (
'ALABAMA' => 'AL',
'ALASKA' => 'AK',
'AMERICAN SAMOA' => 'AS',
'ARIZONA' => 'AZ',
'ARKANSAS' => 'AR',
'CALIFORNIA' => 'CA',
'COLORADO' => 'CO',
'CONNECTICUT' => 'CT',
'DELAWARE' => 'DE',
'DISTRICT OF COLUMBIA' => 'DC',
'FEDERATED STATES OF MICRONESIA' => 'FM',
'FLORIDA' => 'FL',
'GEORGIA' => 'GA',
'GUAM' => 'GU',
'HAWAII' => 'HI',
'IDAHO' => 'ID',
'ILLINOIS' => 'IL',
'INDIANA' => 'IN',
'IOWA' => 'IA',
'KANSAS' => 'KS',
'KENTUCKY' => 'KY',
'LOUISIANA' => 'LA',
'MAINE' => 'ME',
'MARSHALL ISLANDS' => 'MH',
'MARYLAND' => 'MD',
'MASSACHUSETTS' => 'MA',
'MICHIGAN' => 'MI',
'MINNESOTA' => 'MN',
'MISSISSIPPI' => 'MS',
'MISSOURI' => 'MO',
'MONTANA' => 'MT',
'NEBRASKA' => 'NE',
'NEVADA' => 'NV',
'NEW HAMPSHIRE' => 'NH',
'NEW JERSEY' => 'NJ',
'NEW MEXICO' => 'NM',
'NEW YORK' => 'NY',
'NORTH CAROLINA' => 'NC',
'NORTH DAKOTA' => 'ND',
'NORTHERN MARIANA ISLANDS' => 'MP',
'OHIO' => 'OH',
'OKLAHOMA' => 'OK',
'OREGON' => 'OR',
'PALAU' => 'PW',
'PENNSYLVANIA' => 'PA',
'PUERTO RICO' => 'PR',
'RHODE ISLAND' => 'RI',
'SOUTH CAROLINA' => 'SC',
'SOUTH DAKOTA' => 'SD',
'TENNESSEE' => 'TN',
'TEXAS' => 'TX',
'UTAH' => 'UT',
'VERMONT' => 'VT',
'VIRGIN ISLANDS' => 'VI',
'VIRGINIA' => 'VA',
'WASHINGTON' => 'WA',
'WEST VIRGINIA' => 'WV',
'WISCONSIN' => 'WI',
'WYOMING' => 'WY',
);

В качестве отказоустойчивого мы также создадим массив значений состояния a2, так как некоторые поля ваших данных не содержат имен состояний:

$a2Map = array (
0 => 'AL',
1 => 'AK',
2 => 'AS',
3 => 'AZ',
4 => 'AR',
5 => 'CA',
6 => 'CO',
7 => 'CT',
8 => 'DE',
9 => 'DC',
10 => 'FM',
11 => 'FL',
12 => 'GA',
13 => 'GU',
14 => 'HI',
15 => 'ID',
16 => 'IL',
17 => 'IN',
18 => 'IA',
19 => 'KS',
20 => 'KY',
21 => 'LA',
22 => 'ME',
23 => 'MH',
24 => 'MD',
25 => 'MA',
26 => 'MI',
27 => 'MN',
28 => 'MS',
29 => 'MO',
30 => 'MT',
31 => 'NE',
32 => 'NV',
33 => 'NH',
34 => 'NJ',
35 => 'NM',
36 => 'NY',
37 => 'NC',
38 => 'ND',
39 => 'MP',
40 => 'OH',
41 => 'OK',
42 => 'OR',
43 => 'PW',
44 => 'PA',
45 => 'PR',
46 => 'RI',
47 => 'SC',
48 => 'SD',
49 => 'TN',
50 => 'TX',
51 => 'UT',
52 => 'VT',
53 => 'VI',
54 => 'VA',
55 => 'WA',
56 => 'WV',
57 => 'WI',
58 => 'WY',
);

Затем мы можем использовать эти массивы для форматирования ваших данных:

//we'll format the states into this array
$statesFormatted = array();

//if your states data is a string like displayed in your post:
$states = "'plattsburgh, new york'
'California'
'Central Valley,Ca/ Ptld, Oregon'
'Bay area,CA'
'new port richey florida'
'HAMPTON ROADS AREA'
'DC Metro area'
'Pennsylvania, Colorado, New York, Maryland Federal Facilities, Military Facilities,'
";
//read the string into an array, by splitting up the new lines:
$stateFields = explode("\n",$states);

//if your states data is an array:
$stateFields = array(
'plattsburgh, new york',
'California',
'Central Valley,Ca/ Ptld, Oregon',
'Bay area,CA',
'new port richey florida',
'HAMPTON ROADS AREA',
'DC Metro area',
'Pennsylvania, Colorado, New York, Maryland Federal Facilities, Military Facilities,',
);//go through each state field
foreach($stateFields as $field) {
//remove the single quotes?
//$field = str_replace("'","",$field);

//first, we look to try and match a name to a2
foreach($nameToA2Map as $name => $a2) {
//if the name can be found in the field
if(strpos(strtoupper($field),$name) !== false) {
//match!!
$statesFormatted[$field] = $a2;
//we break here, as we don't need to search anymore
break;
}
}

//lets check that we found a match
if(!isset($statesFormatted[$field])) {
//we didn't find a match, lets smartly try and find an a2 value in the field
foreach($a2Map as $a2) {
if(preg_match("/[\W]".$a2."[\W]/", $field) >= 1) {
//match!!
$statesFormatted[$field] = $a2;
//we break here, as we don't need to search anymore
break;
}
}
}

//if we still can't find a match, then we we do some sort of fail-safe here...
if(!isset($statesFormatted[$field])) {
$statesFormatted[$field] = "COULD NOT MATCH!";
}
}

echo "<pre>";
print_r($statesFormatted);
echo "</pre>";

Выше будет выводить:

Array
(
[plattsburgh, new york] => NY
[California] => CA
[Central Valley,Ca/ Ptld, Oregon] => OR
[Bay area,CA] => COULD NOT MATCH!
[new port richey florida] => FL
[HAMPTON ROADS AREA] => COULD NOT MATCH!
[DC Metro area] => COULD NOT MATCH!
[Pennsylvania, Colorado, New York, Maryland Federal Facilities, Military Facilities,] => CO
)

Если вы заметили, что в последних строках кода я делаю последнюю проверку, чтобы увидеть, не может ли поле быть сопоставлено, и присваиваю ему значение «COULD NOT MATCH!». Это поля, в которых введенные пользователем данные слишком противоречивы, чтобы их можно было легко сопоставить. Вы можете либо игнорировать эти поля как противоречивые данные, либо добавить дополнительные условия к $nameToA2Map массив. Я не рекомендовал бы делать это все же.

Надеюсь, это поможет.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]