Php 获取数组中的精确值所需的字符串操作

Php 获取数组中的精确值所需的字符串操作,php,arrays,string,Php,Arrays,String,在访问sms网关提供商api以提交报告时,我有以下动态输出: 919550272832 | 1| id:1187093564 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59 919551370177 | 1| id:1170330677 sub:001 dlvrd:001 submit date:1312191022 don

在访问sms网关提供商api以提交报告时,我有以下动态输出:

919550272832 | 1| id:1187093564 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59
919551370177 | 1| id:1170330677 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59
918558840953 | 1| id:1187093566 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59
918558851999 | 2| id:1170330676 sub:001 dlvrd:001 submit date:1312191022 done date:1312191242 stat:UNDELIV err:027 text: | 2013-12-19 12:42:59
919552673202 | 2| id:1136761922 sub:001 dlvrd:001 submit date:1312191022 done date:1312191242 stat:UNDELIV err:027 text: | 2013-12-19 12:42:59
现在我需要将上面的字符串转换为如下所示的数组:

Array
    (
       [919550272832] => Array
         (
            [id] => 1187093564
            [sub] => 001
            [dlvrd] => 001
            [date] => 1312191022
            [stat] => DELIVRD
            [err] => 000
          )
        [918558851999] => Array
          (
            [id] => 1170330677
            [sub] => 001
            [dlvrd] => 001
            [date] => 1312191022
            [stat] => UNDELIV
            [err] => 027
            )
    )
键:数组中的值格式

我特意从原始输出中删除了一些值,以使数组看起来更好,但如果这些值成为最终数组输出的一部分,我没有问题

有人能帮我提供一些线索或参考资料吗


谢谢你

你可以这样做,但这并不是最好的例子

$lines = array(
    '919550272832 | 1| id:1187093564 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59',
    '919551370177 | 1| id:1170330677 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59',
    '918558840953 | 1| id:1187093566 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59',
    '918558851999 | 2| id:1170330676 sub:001 dlvrd:001 submit date:1312191022 done date:1312191242 stat:UNDELIV err:027 text: | 2013-12-19 12:42:59',
    '919552673202 | 2| id:1136761922 sub:001 dlvrd:001 submit date:1312191022 done date:1312191242 stat:UNDELIV err:027 text: | 2013-12-19 12:42:59',
);

$keys = array(
    'id','sub','dlvrd', 'date', 'stat', 'err'
);

// Create array with key
$newArray = array();

foreach($lines as $string){
    // get the key for our new array. ex: 919550272832  (12 digits regex)
    $key = preg_match('/\d{12}/', $string, $match);
    $key = current($match);

    $newArray[$key] = array();

    foreach($keys as $k => $v){
           // regex prefix till space
           if(preg_match('/'.$v.':(.*?)\s+/', $string, $match))
                $newArray[$key][$v] = $match[1];
     }


}

echo '<pre>';
print_r($newArray);

我认为解决这一问题的最佳方法是使用函数这看起来像是一项。。。正则表达式

您只需使用正则表达式即可拉出每个标题后面的值:

$regex = '/^(\d*) \| \d\| id:(\d*) sub:(\d*) dlvrd:(\d*) submit date:(\d*) done date:(\d*) stat:(\w*) err:(\d*) text: \| (.*)$/m';

$ret = array();
if(preg_match_all($regex, $data, $matches, PREG_SET_ORDER) > 0){
    foreach($matches as $val){
        $ret[$val[1]] = array(
            'id' => $val[2],
            'sub' => $val[3],
            'dlvrd' => $val[4],
            'date' => $val[5],
            'stat' => $val[7],
            'err' => $val[8]
        );
    }
}
为此使用preg_match_all:

$text = '919550272832 | 1| id:1187093564 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59
    919551370177 | 1| id:1170330677 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59
    918558840953 | 1| id:1187093566 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59
    918558851999 | 2| id:1170330676 sub:001 dlvrd:001 submit date:1312191022 done date:1312191242 stat:UNDELIV err:027 text: | 2013-12-19 12:42:59
    919552673202 | 2| id:1136761922 sub:001 dlvrd:001 submit date:1312191022 done date:1312191242 stat:UNDELIV err:027 text: | 2013-12-19 12:42:59';

$lines = explode("\r\n", $text);
foreach($lines as $line){
    $keyVals = explode(" ", $line);
    $output = array();
    foreach($keyVals as $pair){
        $temp = explode(":", $pair);
        if(array_key_exists('1', $temp)){
            $output[$temp[0]] = $temp[1];
        }
    }
    print_r($output);
}

演示:

如果您的SMS服务输出总是这样,假设您需要的信息总是一个按:%分割的键值对,那么您可以通过这种方式进行技术操作。这是超级通用的,所以一定要把你不需要的东西删掉

Array
(
    [id] => 1187093564
    [sub] => 001
    [dlvrd] => 001
    [date] => 1312191022
    [stat] => DELIVRD
    [err] => 000
    [text] =>
    [10] => 22
)
输出:

// load lines from a file
$lines = array(
    '919550272832 | 1| id:1187093564 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59',
    '919551370177 | 1| id:1170330677 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59',
    '918558840953 | 1| id:1187093566 sub:001 dlvrd:001 submit date:1312191022 done date:1312191022 stat:DELIVRD err:000 text: | 2013-12-19 10:22:59',
    '918558851999 | 2| id:1170330676 sub:001 dlvrd:001 submit date:1312191022 done date:1312191242 stat:UNDELIV err:027 text: | 2013-12-19 12:42:59',
    '919552673202 | 2| id:1136761922 sub:001 dlvrd:001 submit date:1312191022 done date:1312191242 stat:UNDELIV err:027 text: | 2013-12-19 12:42:59',
);

// or 
$lines = file_get_contents('myfile.txt');

$output = array();

// process each line    
foreach ($lines as $line) {
    // split parts by the pipe (|) and trim each entry
    $data = explode('|', $line);
    $data = array_map('trim', $data);

    // extract each part to a separate variable
    list($isbn, $i, $params, $date) = $data;

    // extract all colon-separated parameters from the third part
    preg_match_all('/(?P<key>[a-z]+):(?P<value>[a-z0-9]+)/i', $params, $matches);

    // add each parameter to the output array 
    for ($i = 0; $i < count($matches['key']); $i++) {
        $key   = $matches['key'][$i];
        $value = $matches['value'][$i];
        $output[$isbn][$key] = $value;
    }
}

下面是一个工作示例:

array(5) {
  [919550272832]=>
  array(6) {
    ["id"]=>
    string(10) "1187093564"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191022"
    ["stat"]=>
    string(7) "DELIVRD"
    ["err"]=>
    string(3) "000"
  }
  [919551370177]=>
  array(6) {
    ["id"]=>
    string(10) "1170330677"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191022"
    ["stat"]=>
    string(7) "DELIVRD"
    ["err"]=>
    string(3) "000"
  }
  [918558840953]=>
  array(6) {
    ["id"]=>
    string(10) "1187093566"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191022"
    ["stat"]=>
    string(7) "DELIVRD"
    ["err"]=>
    string(3) "000"
  }
  [918558851999]=>
  array(6) {
    ["id"]=>
    string(10) "1170330676"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191242"
    ["stat"]=>
    string(7) "UNDELIV"
    ["err"]=>
    string(3) "027"
  }
  [919552673202]=>
  array(6) {
    ["id"]=>
    string(10) "1136761922"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191242"
    ["stat"]=>
    string(7) "UNDELIV"
    ["err"]=>
    string(3) "027"
  }
}

希望有帮助

哦,好主意,我没意识到这不是提交和约会。。。我不认为用我的方法可以解决这个问题:嘿,没问题,谢谢你的时间和努力有三个日期字段,那么数组中哪一个字段应该作为日期结束呢?我编写了一个PHP类来处理这样的事情。该类默认解析Apache日志文件,但它足够灵活,可以解析这种类型的任何格式文本文件;您只需更改fields类中的正则表达式模式和字段列表。如果你对正则表达式有一点了解,那么为你的文件编写正则表达式模式应该相对简单。到目前为止,你编写了什么代码来解决这个问题?这个问题似乎是离题的,因为到目前为止还没有努力解决这个问题。@james.garriss我正在开发开源whmcs sms模块,它在github上可用。我一直在检索实际的交付状态和其他有用的参数,以使报告看起来更有意义。它工作得很好。。谢谢分享。。我很高兴
array(5) {
  [919550272832]=>
  array(6) {
    ["id"]=>
    string(10) "1187093564"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191022"
    ["stat"]=>
    string(7) "DELIVRD"
    ["err"]=>
    string(3) "000"
  }
  [919551370177]=>
  array(6) {
    ["id"]=>
    string(10) "1170330677"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191022"
    ["stat"]=>
    string(7) "DELIVRD"
    ["err"]=>
    string(3) "000"
  }
  [918558840953]=>
  array(6) {
    ["id"]=>
    string(10) "1187093566"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191022"
    ["stat"]=>
    string(7) "DELIVRD"
    ["err"]=>
    string(3) "000"
  }
  [918558851999]=>
  array(6) {
    ["id"]=>
    string(10) "1170330676"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191242"
    ["stat"]=>
    string(7) "UNDELIV"
    ["err"]=>
    string(3) "027"
  }
  [919552673202]=>
  array(6) {
    ["id"]=>
    string(10) "1136761922"
    ["sub"]=>
    string(3) "001"
    ["dlvrd"]=>
    string(3) "001"
    ["date"]=>
    string(10) "1312191242"
    ["stat"]=>
    string(7) "UNDELIV"
    ["err"]=>
    string(3) "027"
  }
}