* После того, как я написал этот пост, я понял, что слишком много объяснил. Последний раздел в основном суммирует все в TL; DR. Не стесняйтесь переходить прямо к этому. *
RegEx
Это очень длинное регулярное выражение, которое я написал для разбора адреса улицы ( Regex101 Link ):
/^\s*(?:(.*(?:\s+\S+)*(?: Road| Rd| Street| St| Drive| Dr| Avenue| Ave| Av| Lane| Ln| Parkway| Pkwy| Plaza| Plz| Route| Rte| Boulevard| Blvd| Terrace| Ter| Circle| Cir))\s*|([^,]*(?:\s+\S+)*))\s*[,. ]*\s*((?:Suite|Ste|#) ?[A-Z0-9]+)?\s*[,. ]*\s*(?:([^,.]+)\s*[,. ]+\s*([A-Z]{2})\s*[,. ]*\s*([0-9]+)\s*|\s*([^,.]+)\s*[,. ]\s*((?:New|North|Rhode|South|West) ?[A-Z]*)\s*[,. ]+\s*([0-9]+)|\s*([^,.]+)\s*[,. ]+\s*([A-Z]*)\s*[,. ]+\s*([0-9]+))/i
Работает для следующих тестовых случаев:
- Два имени состояния слов (первое слово для всех них - «Новое», «Север», «Род», «Юг» или «Запад»)
123 Example Road, Example Town, North Example 12345
- Имена состояний в одно слово
123 Example Road, Example Town, Example 12345
- Двухбуквенные сокращения для состояний
123 Example Road Example Town NE 12345
- Запятые или точки между всей информацией
123 Example Road, Example Town. NE, 12345
- Нет запятых или точек вообще
123 Example Road Example Town NE 12345
- Дополнительная группа захвата для номера Suite (работает с 'Suite', 'Ste' и '#'
123 Example Road Example Town NE 12345
Есть еще несколько случаев, которые работают , но они имеют определенные недостатки:
- Если название улицы не заканчивается на один из перечисленных опций, он все еще может работать, пока перед названием города стоит запятая.
123 Example, Example Town NE 12345
- работает 123 Example Example Town NE 12345
- не
Как я в настоящее время реализую это
Прямо сейчас, если входная строка имеет сокращенное двухбуквенное состояние (123 Example Rd, Example Town NE 12345
), группы захвата будут:
1) Уличный адрес
2) Город
5) Сокращение штата
6) Почтовый индекс
Если во входной строке есть состояние из двух слов (123 Example Rd, Example Town New York 12345
), группы захвата будут :
1) Адрес улицы
7) Город
8) Штат
9) Почтовый индекс
И если входная строка имеет одно слово состояния (123 Example Rd, Example Town Example 12345
), группы захвата будут:
1) адрес улицы
10) город
11) штат
12) Почтовый индекс
С помощью имеющегося кода я получаю массив захваченных групп на основе входной строки. Я проверяю, являются ли определенные индексы массива нулевыми, чтобы получить данные. Это устаревший код, основанный на старом выражении, но я делаю что-то вроде этого:
if (addr_array != null) {
street_temp = addr_array[1];
if (addr_array[2] != null) {
ste_temp = addr_array[2];
}
if (addr_array[3] != null) {
city_temp = addr_array[3];
state_abv_temp = addr_array[4];
postal_temp = addr_array[5];
} else {
city_temp = addr_array[6];
state_abv_temp = addr_array[7];
postal_temp = addr_array[8];
}
}
Что я хочу сделать (и TL; DR)
В настоящее время существует 12 групп захвата в моем RegEx, но только 5 реальных "переменных", которые я пытаюсь разобрать. Часть состояния адреса может находиться в группе захвата 5, 8 или 11 в зависимости от входной строки. То же самое с городом, но с 4, 7 и 10 ... et c.
Можно ли упростить вещи и сделать так, чтобы каждый фрагмент адресной информации всегда находился в одной и той же группе захвата?