在PHP中从这个复杂字符串中提取有意义的数据

在PHP中从这个复杂字符串中提取有意义的数据,php,Php,我收到了一些PHP应用程序的结构化数据,但格式有些不可预测,难以处理。我对数据的初始格式没有发言权。我得到的是一个字符串(下面给出的示例) 以上是5名足球运动员的数据。这就是我需要得到的: [9484,'Víctor Valdés',8,[[['accurate_pass',[15]],['touches',[42]],['saves',[4]],['total_pass',[24]],['good_high_claim',[2]],['formation_place',[1]]]],1,'GK

我收到了一些PHP应用程序的结构化数据,但格式有些不可预测,难以处理。我对数据的初始格式没有发言权。我得到的是一个字符串(下面给出的示例)

以上是5名足球运动员的数据。这就是我需要得到的:

[9484,'Víctor Valdés',8,[[['accurate_pass',[15]],['touches',[42]],['saves',[4]],['total_pass',[24]],['good_high_claim',[2]],['formation_place',[1]]]],1,'GK',1,0,0,'GK',31,183,78]

[1320,'Carles Puyol',7.76,[[['accurate_pass',[50]],['touches',[75]],['aerial_won',[3]],['total_pass',[55]],['total_tackle',[1]],['formation_place',[6]]]],2,'DC',5,0,0,'D(CLR)',35,178,80]

[5780,'Dani Alves',8.21,[[['accurate_pass',[58]],['touches',[99]],['total_scoring_att',[1]],['total_pass',[66]],['total_tackle',[6]],['aerial_lost',[1]],['fouls',[4]],['formation_place',[2]]]],2,'DR',22,0,0,'D(CR)',30,173,64]

[83686,'Marc Bartra',8.31,[[['accurate_pass',[64]],['touches',[88]],['won_contest',[1]],['total_scoring_att',[1]],['aerial_won',[1]],['total_pass',[66]],['total_tackle',[5]],['aerial_lost',[1]],['fouls',[1]],['formation_place',[5]]]],2,'DC',15,0,0,'D(C)',22,181,70]

[13471,'Adriano',6.72,[[['accurate_pass',[16]],['touches',[28]],['aerial_won',[2]],['total_pass',[18]],['total_tackle',[1]],['formation_place',[3]]]],2,'DL',21,1,31,'D(CLR),M(LR)',29,172,67]
现在,我在上面的示例中手动完成的工作需要用PHP可靠地完成。如您所见,每个播放器都有一组数据。为了将大字符串拆分为单个玩家,我不能用“],[”将其分解,因为子字符串在每个玩家的数据中出现的次数也是不可预测的

每个球员都有一定数量的统计数据(准确传球、触球等),但他们的统计数据并不相同。例如,球员1有“扑救”,其他人没有。球员4有“赢得比赛”其他人没有。没有办法知道谁会有哪些数据。这意味着我不能只计算逗号,直到新球员或类似的东西

每个玩家的名字前都有一个数字,但这个数字的位数无法预测,因此无法将其与字符串中可能出现的其他数字区分开来


我认为所有玩家都经常出现的是最后一位:在最后一个闭括号之前,总是有3个整数除以逗号。这种类型的子字符串(
INT,INT,INT]
)似乎在任何其他情况下都不会出现。也许这会有一些用处?

尝试将其解析为json,然后提取您想要的内容。假设数据分为4块,您可以尝试:

$arr = json_decode($str);
for($i = 0; $i < count($arr) - 3; $i += 4)
{
  $arr[] = new array($arr[$i], $arr[$i + 1], $arr[$i + 2], $arr[$i + 3]);
}
$arr=json\u解码($str);
对于($i=0;$i<计数($arr)-3;$i+=4)
{
$arr[]=新阵列($arr[$i]、$arr[$i+1]、$arr[$i+2]、$arr[$i+3]);
}
一种“困难”的方法是计算括号(在PHP中不太常见,在文本解析语言中更常见)



为什么不将
[
计算在一个循环中?这里有一个未经测试的快速循环,可以让您开始

$output = array('');
$brackets = 0;
$index = 0;
foreach (str_split($input) as $ch) {
    if ($ch == '[') {
        $brackets++;
    }

    $output[$index] .= $ch;

    if ($ch == ']') {
        $brackets--;
        if ($brackets === 0) {
            $index++;
            $output[$index] = '';
        }
    }
}

虽然不是很优雅…

您的字符串看起来像JSON,但它不是有效的JSON,因此
JSON\u decode()
将无法工作

通过将字符串包装成一对
[]
并用双引号替换单引号,可以将您的特定大小写转换为有效的JSON:

$string = str_replace("'", '"', $your_string);
var_dump(json_decode('[' . $string . ']'));


当然,最好的解决方案是确保提供了有效的JSON,因为如果文本字符串包含例如双引号,这将很容易中断。

看起来@Boundless answer是正确的,您可以使用JSON_decode,但是您需要对首先得到的字符串做几件事,它看起来也是有效的JSON格式用绳子捆起来的

这对我很有用:

<?php
$str = "[9484,'Víctor Valdés',8,[[['accurate_pass',[15]],['touches',[42]],['saves',[4]],['total_pass',[24]],['good_high_claim',[2]],['formation_place',[1]]]],1,'GK',1,0,0,'GK',31,183,78],[1320,'Carles Puyol',7.76,[[['accurate_pass',[50]],['touches',[75]],['aerial_won',[3]],['total_pass',[55]],['total_tackle',[1]],['formation_place',[6]]]],2,'DC',5,0,0,'D(CLR)',35,178,80],[5780,'Dani Alves',8.21,[[['accurate_pass',[58]],['touches',[99]],['total_scoring_att',[1]],['total_pass',[66]],['total_tackle',[6]],['aerial_lost',[1]],['fouls',[4]],['formation_place',[2]]]],2,'DR',22,0,0,'D(CR)',30,173,64],[83686,'Marc Bartra',8.31,[[['accurate_pass',[64]],['touches',[88]],['won_contest',[1]],['total_scoring_att',[1]],['aerial_won',[1]],['total_pass',[66]],['total_tackle',[5]],['aerial_lost',[1]],['fouls',[1]],['formation_place',[5]]]],2,'DC',15,0,0,'D(C)',22,181,70],[13471,'Adriano',6.72,[[['accurate_pass',[16]],['touches',[28]],['aerial_won',[2]],['total_pass',[18]],['total_tackle',[1]],['formation_place',[3]]]],2,'DL',21,1,31,'D(CLR),M(LR)',29,172,67]";
$str = '[' . $str . ']';
$str = str_replace('\'','"', $str);


//convert string to array
$arr = json_decode($str);

//now it's a php array so you can access any value
//echo '<pre>';
//print_r( $arr );
//echo '</pre>';

echo $arr [0][1]; //prints "Victor Valdes"
?>

它看起来像是JSON的松散变体。我也这么认为,但是,我对我收到的格式没有发言权,我得到的只是一个巨大的字符串。你可以尝试将其解析为JSON。或者你可以尝试正则表达式。是时候写一个解析器了。当然php有一个pargen库了。每当你自己解析JSON时,你都做错了。谢谢我将试着把它解析为JSON,如果它不起作用,我会尝试你的解决方案。谢谢,虽然我想我必须先做一些重新格式化。我会给它一个镜头并报告。如果它没有按照JSON的方式解析,你可能需要把单引号转换成双引号。这是我唯一能看到的,可以阻止它。sing.我强烈建议在对数据执行任意操作以使其看起来像json之前,先询问数据源应该是什么格式。这可能会以令人困惑的方式破坏未来的数据。
$string = str_replace("'", '"', $your_string);
var_dump(json_decode('[' . $string . ']'));
<?php
$str = "[9484,'Víctor Valdés',8,[[['accurate_pass',[15]],['touches',[42]],['saves',[4]],['total_pass',[24]],['good_high_claim',[2]],['formation_place',[1]]]],1,'GK',1,0,0,'GK',31,183,78],[1320,'Carles Puyol',7.76,[[['accurate_pass',[50]],['touches',[75]],['aerial_won',[3]],['total_pass',[55]],['total_tackle',[1]],['formation_place',[6]]]],2,'DC',5,0,0,'D(CLR)',35,178,80],[5780,'Dani Alves',8.21,[[['accurate_pass',[58]],['touches',[99]],['total_scoring_att',[1]],['total_pass',[66]],['total_tackle',[6]],['aerial_lost',[1]],['fouls',[4]],['formation_place',[2]]]],2,'DR',22,0,0,'D(CR)',30,173,64],[83686,'Marc Bartra',8.31,[[['accurate_pass',[64]],['touches',[88]],['won_contest',[1]],['total_scoring_att',[1]],['aerial_won',[1]],['total_pass',[66]],['total_tackle',[5]],['aerial_lost',[1]],['fouls',[1]],['formation_place',[5]]]],2,'DC',15,0,0,'D(C)',22,181,70],[13471,'Adriano',6.72,[[['accurate_pass',[16]],['touches',[28]],['aerial_won',[2]],['total_pass',[18]],['total_tackle',[1]],['formation_place',[3]]]],2,'DL',21,1,31,'D(CLR),M(LR)',29,172,67]";
$str = '[' . $str . ']';
$str = str_replace('\'','"', $str);


//convert string to array
$arr = json_decode($str);

//now it's a php array so you can access any value
//echo '<pre>';
//print_r( $arr );
//echo '</pre>';

echo $arr [0][1]; //prints "Victor Valdes"
?>