将自定义格式解析为数组

时间:2017-08-06 22:47:20

标签: php arrays regex

我正在尝试将自定义格式的.txt文件转换为数组。

以下是第一行的示例:

[LINETYPE]S [STARTTIME]00:00:00
[LINETYPE]M [TITLE]There For You    [PERFORMER]Martin Garrix & Troye Sivan  [MUSICID]21120  [LABEL]     
[LINETYPE]M [TITLE]Shut Up and Dance    [PERFORMER]Walk The Moon    [MUSICID]20634  [LABEL] 

这种情况继续发展,每天每小时都有一个新的[LINETYPE] S.

现在,我想要实现的是每小时创建一个数组 - 每个值包含另一个数组,括号为键:

array("00:00:00" => array(

          array("LINETYPE" => "M",
          "TITLE" => "There For You",
          "PERFORMER" => "Martin Garrix & Troye Sivan",
          "MUSICID" => "21120",
          "LABEL" => ""),

           array("LINETYPE" => "M",
          "TITLE" => "Shut Up And Dance",
          "PERFORMER" => "Walk The Moon",
          "MUSICID" => "20634",
          "LABEL" => "")
   ), "01:00:00" => array(
   [...]
);

搜索每小时的正则表达式应该是正确的,但似乎preg_split不支持多个捕获组。

到目前为止,我发现的所有答案都处于更基本的层面,比如爆炸式的逗号。

到目前为止,这是我的代码。

$test = get_musiclog("06082017");

$hours = array();

$regex = "(\[LINETYPE\]S\t\[STARTTIME\])((?:(?:[0-2][0-9])|(?:[2][0-3])|(?:[0-9])):(?:[0-5][0-9])(?::[0-5][0-9])?(?:\\s?)?)\n";

if (preg_match_all ("/".$regex."/is", $test, $matches)) {
    foreach($matches[2] as $hour) {
        $hours[$hour] = ""; // Music array
    }
}

在思考这些问题之后,我几乎没有留下任何头发。有人能指出我正确的方向吗?

  • 如何用“[LINETYPE] S [STARTTIME] XX:XX:XX ”拆分字符串,并将时间保留为关键字?
  • 如何知道结构是[key] value \ t和\ n是分隔符,我如何分割其余元素?
  • “阵列中数组内的数组”是否是正确的做法?

1 个答案:

答案 0 :(得分:0)

我的方法主要使用否定的字符类来捕获标记之间的值。为了使正则表达式模式保持相对较轻,可以使用可选的捕获组,以便LINETYPE S之类的短行仍然匹配。

代码:(Pattern Demo)(PHP Demo

$input='[LINETYPE]S [STARTTIME]00:00:00
[LINETYPE]M [TITLE]There For You    [PERFORMER]Martin Garrix & Troye Sivan  [MUSICID]21120  [LABEL]     
[LINETYPE]M [TITLE]Shut Up and Dance    [PERFORMER]Walk The Moon    [MUSICID]20634  [LABEL] 
[LINETYPE]M [TITLE]Subeme La Radio  [PERFORMER]Enrique Iglesias [MUSICID]21105  [LABEL]     
[LINETYPE]C [TITLE]AUTO S2 NON STOP [PERFORMER] [MUSICID]A2-6   [LABEL]     
[LINETYPE]M [TITLE]Uptown Funk  [PERFORMER]Mark Ronson & Bruno Mars [MUSICID]20533  [LABEL]     
[LINETYPE]M [TITLE]Let It Go    [PERFORMER]James Bay    [MUSICID]20839  [LABEL]     
[LINETYPE]S [STARTTIME]01:00:00
[LINETYPE]M [TITLE]There For You    [PERFORMER]Martin Garrix & Troye Sivan  [MUSICID]21120  [LABEL]     
[LINETYPE]M [TITLE]Shut Up and Dance    [PERFORMER]Walk The Moon    [MUSICID]20634  [LABEL]     ';
$pattern='/\[LINETYPE\]([A-Z])\s\[(?:TITLE|STARTTIME)\]([^[\s]*(?: [^[\s]+)*)(?:\s*\[PERFORMER\]([^[ ]*(?: [^[ ]+)*)\s+\[MUSICID\]([^[ ]+)\s+\[LABEL\](\S*(?: \S+)*))?/';
if(!preg_match_all($pattern,$input,$out, PREG_SET_ORDER)){
    echo 'something went wrong';
}else{
    foreach($out as $a){
        if($a[1]=='S'){
            $time=$a[2];
        }else{
            $result[$time][]=["LINETYPE"=>$a[1],"TITLE"=>$a[2],"PERFORMER"=>$a[3],"MUSICID"=>$a[4],"LABEL"=>$a[5]];
        }
    }
}
var_export($result);

输出:

array (
  '00:00:00' => 
  array (
    0 => 
    array (
      'LINETYPE' => 'M',
      'TITLE' => 'There For You',
      'PERFORMER' => 'Martin Garrix & Troye Sivan',
      'MUSICID' => '21120',
      'LABEL' => '',
    ),
    1 => 
    array (
      'LINETYPE' => 'M',
      'TITLE' => 'Shut Up and Dance',
      'PERFORMER' => 'Walk The Moon',
      'MUSICID' => '20634',
      'LABEL' => '',
    ),
    2 => 
    array (
      'LINETYPE' => 'M',
      'TITLE' => 'Subeme La Radio',
      'PERFORMER' => 'Enrique Iglesias',
      'MUSICID' => '21105',
      'LABEL' => '',
    ),
    3 => 
    array (
      'LINETYPE' => 'C',
      'TITLE' => 'AUTO S2 NON STOP',
      'PERFORMER' => '',
      'MUSICID' => 'A2-6',
      'LABEL' => '',
    ),
    4 => 
    array (
      'LINETYPE' => 'M',
      'TITLE' => 'Uptown Funk',
      'PERFORMER' => 'Mark Ronson & Bruno Mars',
      'MUSICID' => '20533',
      'LABEL' => '',
    ),
    5 => 
    array (
      'LINETYPE' => 'M',
      'TITLE' => 'Let It Go',
      'PERFORMER' => 'James Bay',
      'MUSICID' => '20839',
      'LABEL' => '',
    ),
  ),
  '01:00:00' => 
  array (
    0 => 
    array (
      'LINETYPE' => 'M',
      'TITLE' => 'There For You',
      'PERFORMER' => 'Martin Garrix & Troye Sivan',
      'MUSICID' => '21120',
      'LABEL' => '',
    ),
    1 => 
    array (
      'LINETYPE' => 'M',
      'TITLE' => 'Shut Up and Dance',
      'PERFORMER' => 'Walk The Moon',
      'MUSICID' => '20634',
      'LABEL' => '',
    ),
  ),
)