REGEX для захвата только адресных блоков и исключения текста, разделенного пустыми строками - PullRequest
0 голосов
/ 03 апреля 2020

У меня большой документ с адресными блоками, который содержит множество различных форматов адресов.

В документе есть разделы с абзацами, рисунками и произвольным текстом, и в этих разделах есть большие группы адресных блоков. Адресные блоки всегда будут иметь пустую строку до и после адреса, и они всегда будут заканчиваться ZIP (+4 необязательно).

К сожалению, адреса различаются настолько, что я не могу придумать способ для захвата определенных c компонентов (иногда есть только получатель, а другие есть получатель и строка ATTN. Иногда есть адрес дополнительного устройства и т. д. c ..).

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

Мой шаблон:

[regex]$pattern = "(?xm)\n(
^[\w\d\-\.\s]+(\d{5})(?:\-\d{4})?
)";

Пример того, что это такое захват:

       DUSHANBE PLACEISTAN

       DASHB FARMINTON
       PSC 123 BOX 1
       APO AP 12345




       DETACHMENT ATTACHMENT
       SECURITY GUARD OFFICE
       AMERICAN EMB E01
       UNIT 1712
       APO AE 54321-7798

       TASHKENT UZBEKISTAN

       TONE TENTKASH DOS
       75485 TORSHEN PL
       WASHINGTON DC 12345-1234

В приведенном выше примере не должно быть захвата DUSHANBE PLACEISTAN или TASHKENT UZBEKISTAN (только блоки адресов).

Любой и понимание того, как правильно анализировать текст будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 03 апреля 2020

Если перед первой строкой должна быть новая строка, вы также можете использовать утверждение обратной строки для новой строки и сопоставлять как можно меньше строк, пока не найдете соответствующий формат почтового индекса.

(?<=\r?\n)(?:\S.*\r?\n)+?.*\d{5}(?:\-\d{4})?$

Пояснение

  • (?<=\r?\n) Позитивный взгляд за спиной, утверждение, что слева - новая строка
  • (?: Группа без захвата
    • \S.*\r?\n Соответствует всей строке, начиная с непробельного символа, предотвращающего пустые строки
  • )+? Закройте группу и повторите 1+ раз без жадности
  • .*\d{5}(?:\-\d{4})? Соответствует всей строке, заканчивающейся на шаблоне почтового индекса
  • $ Конец строки

Regex demo

Альтернативный шаблон может соответствовать всем строкам, которые не заканчиваются шаблоном почтового индекса, пока вы не встретите строки, которые это делают.

(?<=\r?\n)(?:(?!.*\d{5}(?:\-\d{4})?$)\S.*\r?\n)+.*\d{5}(?:\-\d{4})?$

Regex demo

0 голосов
/ 03 апреля 2020

Полагаю, вы могли бы использовать регулярное выражение

(?:^\w+(?: +\w+)* *\r?\n)+\w+(?: +\w+)* +\d{5}(?:\-\d{4})? *$

Демо

Движок регулярных выражений выполняет следующие операции (я экранировал символ пробела, чтобы сделать они более заметны).

(?:           # begin non-cap grp
  ^           # match beginning of line
  \w+         # match 1+ word chars
  (?:\ +\w+)  # match 1+ spaces, 1+ word chars in non-cap grp
  *           # execute non-cap grp 0+ times
  \ *\r?\n    # match 0+ spaces, return char(s) 
)             # end non-cap grp             
+             # execute non-cap grp 1+ times
\w+           # match 1+ word chars
(?:\ +\w+)    # match 1+ spaces, 1+ word chars in non-cap grp
*             # execute non-cap grp 0+ times
\ +           # match 1+ spaces
\d{5}         # match 5 digits
(?:\-\d{4})   # match '-' then 4 digits in non-cap grp
?             # optionally match non-cap grp
\ *           # match 0+ spaces
$             # match end of line
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...