Можно ли определить номер группы захвата RegEx при использовании оператора чередования (ИЛИ) для нескольких случаев? - PullRequest
0 голосов
/ 07 апреля 2020

* После того, как я написал этот пост, я понял, что слишком много объяснил. Последний раздел в основном суммирует все в 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.

Можно ли упростить вещи и сделать так, чтобы каждый фрагмент адресной информации всегда находился в одной и той же группе захвата?

...