php - 将格式化文本文件解析为 PHP 数组

标签 php regex arrays parsing

我需要将文本文件解析为 php 数组。这是我的文本文件:

file: slide1.jpg    | title: Title here                     | description: Aenean eleifend ultrices leo at venenatis. Suspendisse luctus    | crop: top
file: slide2.jpg    | description: Phasellus ac tortor ut dolor blandit tincidunt   | title: Nullam cursus                                  | crop: bottom
file: slide3.jpg    | title: Hendrerit lacinia nisl         | description: Tortor ut dolor blandit tincidunt                                | crop: bottom
file: slide4.jpg    | title: Morbi hendrerit lacinia nisl   | description: Maecenas venenatis lectus vitae                                  | crop: left

我想将它解析成这样的结构化数组:

array(4) {
  "slide1.jpg" => array (
    "title"  => "Title here",
    "description"  => "Aenean eleifend ultrices leo at venenatis. Suspendisse luctus",
    "crop"  => "top"
  ),
  "slide2.jpg" => array (
    "title"  => "Nullam cursus",
    "description"  => "Phasellus ac tortor ut dolor blandit tincidunt",
    "crop"  => "top"
  ),
  "slide3.jpg" => array (
    "title"  => "Hendrerit lacinia nisl",
    "description"  => "Tortor ut dolor blandit tincidunt",
    "crop"  => "top"
  ),
  "slide4.jpg" => array (
    "title"  => "Morbi hendrerit lacinia nisl",
    "description"  => "Maecenas venenatis lectus vitae",
    "crop"  => "top"
  )
}

我尝试了许多重复的 foreach 语句,但效率不高,而且代码变得非常冗长。有谁知道一种更简单的方法吗?

最佳答案

首先:小心!

这可能是一件很棘手的事情,但也有许多可能的异常(exception)。我提供的解决方案是:

  • ...不使用正则表达式,这应该使代码更具可读性、可维护性,yada yada yada :)
  • ...不检查值是否包含管道|,这会导致这个问题。另一方面,值可以安全地包含冒号。
  • ...不处理多字节字符。
  • ...不关心性能。
  • ...假设 key “file”始终存在。
  • ...不插入缺失的键,在这种情况下应该在其他地方处理。

在盲目复制/粘贴之前请考虑这些注释! ;)

此外,我的解决方案在每个元素中都包含文件名,这是多余的。但删除它会使解决方案变得更加困惑,而且没有太多值(value)。

解决方案如下:

<?php

/**
* Parse a line of the file. Returns an associative array, using the part 
* before the colon as key, the following part as value.
*
* @param $line A line of text.
*/
function parse_line($line) {
  // split on each '|' character.
  $fields = explode('|', $line);
  $data = array();
  foreach($fields as $field) {
    // unpack key/value from each 'key: value' text. This will only split on 
    // the first ":", so the value may contain colons.
    list($key, $value) = explode(':', $field, 2);
    // remove surrounding white-space.
    $key = trim($key);
    $value = trim($value);
    $data[$key] = $value;
  }
  return $data;
}


/**
* Parses a file in the specified format.
*
* Returns an associative array, where the key is a filename, and the value is 
* an associative array of metadata.
*
* @param $fname The filename
*/
function parse_file($fname) {
  $handle = fopen($fname, "r");
  $lines = array();
  if ($handle) {
    while (($line = fgets($handle)) !== false) {
      $data = parse_line($line);
      $lines[$data["file"]] = $data;
    }
  } else {
    // error opening the file.
  }
  return $lines;
}

var_dump(parse_file("testdata.txt"));

关于php - 将格式化文本文件解析为 PHP 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22151757/

相关文章:

php - PHP正则表达式查找第一个youtube链接

C++ 重载数组运算符

javascript - X 单击后如何禁用按钮?

php - Laravel Lighthouse - 按关系属性对查询进行排序

php - 此 pdf 数字签名正确吗? PHP/TCPDF

php - 多维数组上的 array_unshift

c - 如果我在Ruby中 pry Array,那么pretty_print函数从哪里来

php - 根据页面更改主体类别

regex - 指数正则表达式问题

regex - 用户名不能包含重复的下划线或句点