1

I'm trying to find two patterns in a text file with PHP.

Text file looks like this:

[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
    )

And my PHP code looks like this:

$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]);
}

It works well but I'm getting [amount] => 33450 two times because "amount" is two times in text file.

I need to get "amount" and "authorizationCode" values only inside in this part of the text file:

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

Could someone help me please?? I'll be grateful.

I think my problem is in regular expression:

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

I should modify that to find only patters inside [detailOutput] => wsTransactionDetailOutput Object(

Thanks you!

Nacho Sarmiento
  • 463
  • 3
  • 8
  • 17
  • 1
    Can you access the data as an object instead? And is the order of the fields always the same? – The fourth bird Jun 03 '20 at 19:09
  • 1
    This will get you the values, but it currently depends on the order `^\h*\[detailOutput] => .*(?:\R(?!\h*\[authorizationCode]).*)*\R\h*(\[authorizationCode] => \d+)(?:\R(?!\h*\[amount]).*)*\R\h*(\[amount] => \d+)` https://regex101.com/r/HtF0KM/1/ – The fourth bird Jun 03 '20 at 19:15
  • Hi @Thefourthbird, thanks for your help! It works perfectly in your regex101 but not in my php code :( Do you see something wrong in preg_match_all() function? I just replaced your regex in $pattern variable. Thanks for all! :) – Nacho Sarmiento Jun 09 '20 at 03:25
  • I have added an answer with an example. – The fourth bird Jun 10 '20 at 10:59

1 Answers1

0

You could use 2 capturing groups. First match the [detailOutput] part followed by matching all lines that do not start with authorizationCode and capture the values for authorizationCode and amount.

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

Explanation

  • ^ Start of string
  • \h*\[detailOutput] => .* Match [detailOutput] => followed by the rest of the line
  • (?:\R(?!\h*\[authorizationCode]).*)* Repeat matching all lines that do not start with [authorizationCode]
  • \R\h* Match a unicode newline sequence and 0+ horizontal whitespace chars
  • ( Capture group 1
    • \[authorizationCode] => \d+ Match [authorizationCode] => and 1+ digits
  • ) Close group
  • (?:\R(?!\h*\[amount]).*)*\R\h* Match all lines that do not start with [amount]
  • ( Capture group 2
    • \[amount] => \d+ Match [amount] => and 1+ digits
  • )

Regex demo | Php demo

Example code

$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]);
}

Output

[detailOutput] => wsTransactionDetailOutput Object
    (
        [authorizationCode] => 001122
        [paymentTypeCode] => VD
        [responseCode] => 0
        [sharesNumber] => 0
        [amount] => 33450
[authorizationCode] => 001122
[amount] => 33450
The fourth bird
  • 154,723
  • 16
  • 55
  • 70