donglun4682
2019-07-19 14:45
浏览 250
已采纳

php - 如何使用等号=符号的字符串值从数组中提取值而不使用preg_match

I have received a response from server as a string, which I converted as array, but still I am not able to make out, how I can access values from this array like

myarrray['txn_status'];

as also from the string clnt_rqst_meta

array(13) {
  [0]=>
  string(15) "txn_status=0399"
  [1]=>
  string(15) "txn_msg=failure"
  [2]=>
  string(55) "txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161"
  [3]=>
  string(17) "clnt_txn_ref=9178"
  [4]=>
  string(15) "tpsl_bank_cd=NA"
  [5]=>
  string(19) "tpsl_txn_id=T245107"
  [6]=>
  string(14) "txn_amt=121.00"
  [7]=>
  string(47) "clnt_rqst_meta={mob:9937253528}{custname:pawan}"
  [8]=>
  string(16) "tpsl_txn_time=NA"
  [9]=>
  string(15) "tpsl_rfnd_id=NA"
  [10]=>
  string(10) "bal_amt=NA"
  [11]=>
  string(47) "rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0"
  [12]=>
  string(45) "hash=3cf25909ec73865d3200bc267119d3fcc21df463"
}

I know that the same can be achieved using regex/preg_match, but I am sure there must be some straight forward way to achieve it.

update: the actual string received from response is like this:

string(342) "txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463" 

so I used $response =explode("|",$response_str);

图片转代码服务由CSDN问答提供 功能建议

我收到服务器的响应字符串,我将其转换为数组,但我仍然无法 如何,我可以如何访问此数组中的值,如

myarrray ['txn_status'];

来自字符串 clnt_rqst_meta

  array(13){
 [0] => 
 string(15)“txn_status = 0399”\  n [1] => 
 string(15)“txn_msg = failure”
 [2] => 
 string(55)“txn_err_msg =已取消的事务:错误代码TPPGE161”
 [3] =>  
 string(17)“clnt_txn_ref = 9178”
 [4] => 
 string(15)“tpsl_bank_cd = NA”
 [5] => 
 string(19)“tpsl_txn_id = T245107”\  n [6] => 
 string(14)“txn_amt = 121.00”
 [7] => 
 string(47)“clnt_rqst_meta = {mob:9937253528} {custname:pawan}”
 [8  ] => 
 string(16)“tpsl_txn_time = NA”
 [9] => 
 string(15)“tpsl_rfnd_id = NA”
 [10] => 
 string(10)“bal_amt  = NA“
 [11] => 
 string(47)”rqst_token = cd3f6f55-5990-4c3b-bb12-238eede827a0“
 [12] => \  n string(45)“hash = 3cf25909ec73865d3200bc267119d3fcc21df463”
} 
   
 
 

我知道使用regex / preg_match可以实现同样的目的,但我相信必须有 一些直接的实现方法。

更新:从响应中收到的实际字符串是这样的:

  string(342)“  txn_status = 0399 | txn_msg =失败| txn_err_msg =已取消的事务:错误代码TPPGE161 | clnt_txn_ref = 9178 | tpsl_bank_cd = NA | tpsl_txn_id = T245107 | txn_amt = 121.00 | clnt_rqst_meta = {mob:9937253528} {custname:pawan} | tpsl_txn_time = NA |  tpsl_rfnd_id = NA | bal_amt = NA | rqst_token = cd3f6f55-5990-4c3b-bb12-238eede827a0 | hash = 3cf25909ec73865d3200bc267119d3fcc21df463“
   
 
 

所以我用 $ response = explode(“|”,$ response_str);

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • dongliugu8843 2019-07-19 14:59
    已采纳

    You could let the PHP function parse_str() do the heavy lifting for you but it expects to receive a standard query string, with the entries separated by &. Your input string uses a different separator (|) and parse_str() does not provide a way to tell it what character to use as separator.

    The problem has a very simple solution: use str_replace() to replace | to & in the input string then pass the result to parse_str():

    $input = 'txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463';
    parse_str(str_replace('|', '&', $input), $output);
    
    print_r($output);
    

    It produces:

    Array
    (
        [txn_status] => 0399
        [txn_msg] => failure
        [txn_err_msg] => Transaction Cancelled : ERROR CODE TPPGE161
        [clnt_txn_ref] => 9178
        [tpsl_bank_cd] => NA
        [tpsl_txn_id] => T245107
        [txn_amt] => 121.00
        [clnt_rqst_meta] => {mob:9937253528}{custname:pawan}
        [tpsl_txn_time] => NA
        [tpsl_rfnd_id] => NA
        [bal_amt] => NA
        [rqst_token] => cd3f6f55-5990-4c3b-bb12-238eede827a0
        [hash] => 3cf25909ec73865d3200bc267119d3fcc21df463
    )
    

    See it in action: https://3v4l.org/KBaof

    Warning

    The solution exposed above works fine only if the input string does not contain & and %. These characters are special in query strings, parse_str() tries to interpret them using their special meaning and the code above breaks.

    A solution that works when & or % is present in the input string

    $input = 'txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463';
    $output = array_reduce(
        explode('|', $input),
        function($acc, $item) {
            list($key, $value) = explode('=', $item, 2);
            $acc[$key] = $value;
            return $acc;
        },
        []
    );
    
    print_r($output);
    

    It still fails if | is present in the values (e.g. ...|txn_err_msg=a|b|clnt_txn_ref=...) but this issue doesn't have a solution because of the naive encoding of the input string.

    If you can modify the server that produces the input data, change it to produce JSON output. JSON is a format that allows validation of the input string and PHP provides functions to encode and decode it. The code becomes cleaner on both sides.

    点赞 评论
  • donglang5157 2019-07-19 14:53

    Try this:

    $newArray = [];
    foreach ($myArray as $element) {
        $exploded = explode('=', $element);
        $newArray[$exploded[0]] = $exploded[1];
    }
    
    点赞 评论
  • doudou5023 2019-07-19 14:54

    I'm guessing that this expression might return the desired matches:

    ([^=]+)=([^=]+)(?:\||$)
    

    Test

    $re = '/([^=]+)=([^=]+)(?:\||$)/m';
    $str = 'txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463';
    
    preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
    
    var_dump($matches);
    

    The expression is explained on the top right panel of this demo if you wish to explore/simplify/modify it.

    点赞 评论
  • dtnnpt11795 2019-07-19 14:58

    This any help?

    $string = "txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463";
    txn_status = ""; 
    foreach(explode('|', $string) as $val){
        $temp = explode('=', $val);
        //$temp[0] is left side of =
        //$temp[1] is right side of =
        if($temp[0] == "txn_status"){
            txn_status = $temp[1];
        }
    }
    
    点赞 评论
  • dqjl0906 2019-07-19 15:23

    you also can use sscanf. this is not regex but still using some pattern but is more clean than preg_match

    $arr = ['key1=value1', 'key2=value2', 'key3=value3'];
    
    foreach ($arr as $str) {
        sscanf($str, "%[^=]=%[^=]", $key, $value);
        echo "[$key => $value]";
    }
    
    点赞 评论

相关推荐 更多相似问题