Разделение строк детализации транзакции AMEX с помощью регулярных выражений

У меня есть массив строк описания транзакций с карты American Express, которые я буду использовать PHP preg_split() разобрать;

[
"THE DISNEY STORE #90DANBURY             CT",
"CHRISTMAS TREE SHOPSDANBURY             CT",
"BATH & BODY WORKS 07DANBURY             CT",
"CITGO DODGINGTOWN GANEWTOWN             CT",
"DUNKIN #344944 Q35 3MONROE              CT",
"DUNKIN #344944 Q35 3MONROE              CT",
"DUNKIN #344944 Q35 3MONROE              CT",
"DUNKIN #344944 Q35 3MONROE              CT",
"AT&T RECURR BILL PAYDALLAS              TX",
"SHELL OIL 5754389960NEWTOWN             CT",
"POSTAGE REFILL      STAMFORD            CT",
"SHELL OIL 5754389960NEWTOWN             CT",
"ONLINE PAYMENT - THANK YOU",
"SHELL OIL 5754389960NEWTOWN             CT",
"AOL SERVICE         800-827-6364        VA",
"SHELL OIL 5754389960NEWTOWN             CT",
"EBAY INC. 0000      866-779-3229        CA",
"WWW.ITUNES.COM/BILL CUPERTINO           CA",
"THE HOME DEPOT      TRUMBULL            CT",
"THE HOME DEPOT      TRUMBULL            CT",
"AMEX GIFT CARDS     866-268-0582        NY",
"APPLE ONLINE STORE  CUPERTINO           CA",
"APPLE ONLINE STORE  CUPERTINO           CA",
"AMAZON MKTPLACE PMTSAMZN.COM/BILL       WA",
"THE HOME DEPOT      BRIDGEPORT          CT",
"AT&T RECURR BILL PAYDALLAS              TX",
"SHELL OIL 5754389960NEWTOWN             CT",
"AT&T RECURR BILL PAYDALLAS              TX",
"SHELL OIL 5754389960NEWTOWN             CT",
"WALGREENS           NEWTOWN             CT",
"THE HOME DEPOT      TRUMBULL            CT",
"ONLINE PAYMENT - THANK YOU",
"AOL SERVICE         800-827-6364        VA"]

Я пытаюсь разобрать город и штат поставщика из строки описания. Эти данные находятся в CSV, который загружается в скрипт PHP. Использование онлайн-инструмента regexr.com Мне удалось подобраться с помощью этого выражения:

([A-Z&0-9 ./#\*\-]{0,19})\w

То, что я смог вывести, — это максимум 20 символов для описания, за исключением случая с платежами, текст продолжается. Город начинается с ограничения в 20 символов и в некоторых случаях может содержать пробелы. Состояние — 2 символа с предшествующим пробелом.

Ожидаемые результаты:

CHRISTMAS TREE SHOPSDANBURY             CT

Разобрался бы с

Производитель: CHRISTMAS TREE SHOPS Город: DANBURY Государственный: CT

платежи;

ONLINE PAYMENT - THANK YOU

Останется как есть.

И крайние случаи;

AOL SERVICE         800-827-6364        VA

Разобрался бы с

Производитель: AOL SERVICE Деталь: 800-827-6364 Государственный: VA

(Этикетки использовал для наглядности)

Фактические результаты:

если вы посмотрите на мои сохраненные результаты https://regexr.com/3j39m Вы можете увидеть, что строки, как ONLINE PAYMENT - THANK YOU а также AOL SERVICE 800-827-6364 VA не разбирай как положено

Как я могу улучшить выражение, чтобы:

  1. Разбор первых 20 или менее символов в поставщике / описании.
  2. Обработайте описание платежа, в котором отсутствуют 3 ожидаемые части.
  3. Обработайте случаи, когда поставщик подставил другую информацию в ожидаемое местоположение города, которая может превышать ограничение в 20 символов.

1

Решение

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

<?php

$re = '/(?<Store>.{20})(?<City>.{20})(?<State>.{2})/m';
$str = 'THE DISNEY STORE #90DANBURY             CT';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

foreach( $matches as $match ){
echo $match[1]."\t=>\t".$match[2]."\t=>\t".$match[3]."\n";
}

демонстрация.

Вы можете добиться того же с substr(),

1

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

Мне кажется, что список разделен табуляцией, поэтому это должно сработать: /\t([A-Za-z ]+)\t+[A-Za-z]{2}$/

объяснение

  • \t соответствовать вкладке
  • ([A-Za-z ]+) сопоставить строку символов и пробелов, обозначающих название города
  • \t+ соответствовать одной или нескольким вкладкам (похоже, их может быть больше одной в вашем наборе данных)
  • [A-Za-z]{2} соответствует 2 символам, обозначающим аббревиатуру штата
  • $ конец строки
-1