使用正则表达式拆分 AMEX 交易详细信息字符串

Split AMEX Transaction detail strings using regex

我有一组来自美国运通卡的交易描述字符串,我将使用 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 个字符的限制开始,在某些情况下允许包含 whitespace。状态为 2 个字符,前面为白色 space.

预期结果:

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 YOUAOL SERVICE 800-827-6364 VA 这样的行没有按预期解析。

如何将表达式改进为:

  1. 解析 vendor/description 中的前 20 个或更少的字符。
  2. 处理缺少 3 个预期部分的付款说明。
  3. 处理供应商将其他信息替换到可能超过 20 个字符限制的预期城市位置的情况。

在我看来,列表好像是用制表符分隔的,所以这应该可以解决问题:/\t([A-Za-z ]+)\t+[A-Za-z]{2}$/

说明

  • \t 匹配制表符
  • ([A-Za-z ]+)匹配一串字符和空格,表示城镇名称
  • \t+ 匹配一个或多个选项卡(看起来它在您的数据集中可能不止一个)
  • [A-Za-z]{2}匹配2个字符,表示一个州缩写
  • $ 字符串结尾

您可以使用正则表达式拆分固定宽度的字符串,如下所示:

<?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";
}

Demo.

您可以使用 substr() 实现相同的效果。