【发布时间】:2018-10-11 02:37:24
【问题描述】:
我有一个 PHP 应用程序,它与支付处理器接口以处理信用卡。有时,来自处理器的后响应失败(例如矩阵中的瞬间故障),我们没有收到付款的自动通知。在这些情况下,我们回退到从始终发送的确认电子邮件中输入数据。我希望我的代码解析出电子邮件的文本以获取数据,这似乎是 preg_match_all 的完美用例。问题是电子邮件格式错误:它以 name : value 对出现,但它们都在一行上,而且值通常是空白的,这让我很困惑。
我非常擅长正则表达式基础知识(量词、分组、字符类、锚点、修饰符),但对前瞻和后向引用真的没有经验,而且我也不知道它们是否能提供帮助。
示例数据可能看起来像这样(同样,这些都在一行上,只是为了便于阅读而进行了包装):
bypass_first_page : x_company : x_cust_id : 12345 x_customer_ip : x_customer_tax_id:x_description:98765 x_duty:x_email_customer: an_example@example.com x_fax : x_footer_email_receipt : x_fp_hash : 747ffddfe4e106a9c67363ebff996ad x_fp_timestamp:1525100766 x_invoice_num : R000098765 x_login : MY-LOGIN-ID x_logo_url : x_merchant_email : x_method : x_phone : (416) 555-1212 x_po_num : x_receipt_link_method:获取 x_reference_3:1234 x_relay_response: 真 x_relay_url :
我想要如下所示的输出:
[
[bypass_first_page] =>
[x_company] =>
[x_cust_id] => 12345
[x_customer_ip] =>
[x_customer_tax_id] =>
[x_description] => 98765
[x_duty] =>
[x_email_customer] => an_example@example.com
[x_fax] =>
[x_footer_email_receipt] =>
[x_fp_hash] => 747ffeddfe4e106a9c67363ebff996ad
[x_fp_timestamp] => 1525100766
[x_invoice_num] => R000098765
[x_login] => MY-LOGIN-ID
[x_logo_url] =>
[x_merchant_email] =>
[x_method] =>
[x_phone] => (416) 555-1212
[x_po_num] =>
[x_receipt_link_method] => GET
[x_reference_3] => 1234
[x_relay_response] => TRUE
[x_relay_url] =>
]
需要注意的重要事项:
- 字段名称大多(但不限于)以 x_ 开头。如果只能找到需要这个的解决方案,它可能是可行的。
- 字段名称没有包含空格。
- 某些字段名称中包含数字。
- 值可以包含空格(例如电话号码)和下划线(例如电子邮件地址)。
- 当没有值时,冒号和下一个字段名之间只有一个空格。
我最接近的是:
/([\w\d_]+) ?: ([^:]+)/
但这会产生如下输出:
[
[bypass_first_page] => x_company
[x_cust_id] => 12345 x_customer_ip
[x_customer_tax_id] => x_description
...
]
正如您从this regex101 link 中看到的那样,这是失败的,因为存在与任何内容都不匹配的冒号,并且字段名称最终出现在值中(单独或与实际值连接)。我觉得如果有一个修饰符要求匹配整个字符串,或者锚点以某种方式指示一个匹配必须从前一个匹配结束的地方开始,这可以很容易地解决这个问题,但我找不到任何提及任何地方都有这样的事情。可能只是我不知道那东西叫什么?
【问题讨论】:
-
支付网关是否不提供用于核对支付的 API?
12345和x_customer_ip之间缺少:是您的示例数据中的错误,还是在回复电子邮件中出现这样的错误?使用explode(' x_', $string);之类的东西可能会让你更幸运 -
@fubar,在
12345和x_customer_ip之间没有:: 因为12345是前一个字段的值。值之后没有:s,只是在名称和值之间。关于 API 的好主意,我会看看是否存在。 -
好的,知道了。干杯。