【问题标题】:Find two patterns within a specific object in a text file在文本文件的特定对象中查找两个模式
【发布时间】:2020-09-22 14:50:18
【问题描述】:

我正在尝试使用 PHP 在文本文件中查找两种模式。

文本文件如下所示:

[transactionDetails] => wsTransactionDetail Object
    (
        [sharesAmount] => 
        [sharesNumber] => 
        [amount] => 33450
        [commerceCode] => 1234567890
        [buyOrder] => 123321
    )

[detailOutput] => wsTransactionDetailOutput Object
    (
        [authorizationCode] => 001122
        [paymentTypeCode] => VD
        [responseCode] => 0
        [sharesNumber] => 0
        [amount] => 33450
        [commerceCode] => 1234567890
        [buyOrder] => 123321
    )

我的 PHP 代码如下所示:

$pattern1 = preg_quote("authorizationCode", '/');
$pattern2 = preg_quote("amount", '/');

$pattern = "/^.*($pattern1).*\$|($pattern2).*\$/m";

if(preg_match_all($pattern, $contents, $matches)){
   echo "Founds:\n";
   echo implode("\n", $matches[0]);
}

效果很好,但我得到 [amount] => 33450 两次,因为“amount”在文本文件中是两次。

我需要仅在文本文件的这一部分中获取“amount”和“authorizationCode”值:

[detailOutput] => wsTransactionDetailOutput Object
    (
        [authorizationCode] => 001122
        [paymentTypeCode] => VD
        [responseCode] => 0
        [sharesNumber] => 0
        [amount] => 33450
        [commerceCode] => 1234567890
        [buyOrder] => 123321
    )

有人可以帮帮我吗?我将不胜感激。

我认为我的问题在于正则表达式:

/^.*($pattern1).*\$|($pattern2).*\$/m

我应该修改它以仅在 [detailOutput] => wsTransactionDetailOutput Object(

中查找模式

谢谢!

【问题讨论】:

  • 您可以将数据作为对象访问吗?字段的顺序是否始终相同?
  • 这将为您获取值,但目前取决于订单^\h*\[detailOutput] => .*(?:\R(?!\h*\[authorizationCode]).*)*\R\h*(\[authorizationCode] => \d+)(?:\R(?!\h*\[amount]).*)*\R\h*(\[amount] => \d+)regex101.com/r/HtF0KM/1
  • 嗨@Thefourthbird,感谢您的帮助!它在您的 regex101 中完美运行,但在我的 php 代码中却不适用
  • 我已经添加了一个带有示例的答案。

标签: php regex pattern-matching text-files


【解决方案1】:

您可以使用 2 个捕获组。首先匹配[detailOutput] 部分,然后匹配所有不以authorizationCode 开头的行并捕获authorizationCode 和amount 的值。

^\h*\[detailOutput] => .*(?:\R(?!\h*\[authorizationCode]).*)*\R\h*(\[authorizationCode] => \d+)(?:\R(?!\h*\[amount]).*)*\R\h*(\[amount] => \d+)

解释

  • ^ 字符串开始
  • \h*\[detailOutput] => .* 匹配 [detailOutput] => 后跟该行的其余部分
  • (?:\R(?!\h*\[authorizationCode]).*)* 重复匹配所有不以[authorizationCode] 开头的行
  • \R\h* 匹配一个 unicode 换行序列和 0+ 个水平空白字符
  • ( 捕获第 1 组
    • \[authorizationCode] => \d+ 匹配 [authorizationCode] => 和 1+ 位
  • )关闭群
  • (?:\R(?!\h*\[amount]).*)*\R\h*匹配所有不以[amount]开头的行
  • ( 捕获第 2 组
    • \[amount] => \d+ 匹配 [amount] => 和 1+ 位
  • )

Regex demo | Php demo

示例代码

$contents = <<<DATA
[transactionDetails] => wsTransactionDetail Object
    (
        [sharesAmount] => 
        [sharesNumber] => 
        [amount] => 33450
        [commerceCode] => 1234567890
        [buyOrder] => 123321
    )

[detailOutput] => wsTransactionDetailOutput Object
    (
        [authorizationCode] => 001122
        [paymentTypeCode] => VD
        [responseCode] => 0
        [sharesNumber] => 0
        [amount] => 33450
        [commerceCode] => 1234567890
        [buyOrder] => 123321
    )
DATA;

$pattern = "~^\h*\[detailOutput] => .*(?:\R(?!\h*\[authorizationCode]).*)*\R\h*(\[authorizationCode] => \d+)(?:\R(?!\h*\[amount]).*)*\R\h*(\[amount] => \d+)~m";

if(preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER, 0)){
    echo "Founds:\n";
    echo implode("\n", $matches[0]);
}

输出

[detailOutput] => wsTransactionDetailOutput Object
    (
        [authorizationCode] => 001122
        [paymentTypeCode] => VD
        [responseCode] => 0
        [sharesNumber] => 0
        [amount] => 33450
[authorizationCode] => 001122
[amount] => 33450

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 2012-07-24
    相关资源
    最近更新 更多