將格式化文本文件解析為PHP數組

[英]Parse a formatted text file into PHP array


I need to parse a text file into php array. Here is my text file :

我需要將一個文本文件解析為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

I want to parse it into such structured array :

我想把它解析成這樣的結構化數組:

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"
  )
}

I tried with a many repetitive foreach statements but it was not so efficient and the code got very lengthy. Does anybody know a way to achieve it simpler.

我嘗試了很多重復的語句,但是效率不高,代碼也很長。有人知道一種更簡單的方法嗎?

3 个解决方案

#1


4  

First of all: Be Careful!

首先:小心!

This is potentially hairy thing with many possible exceptions. The solution I provide does:

除了很多可能的例外,這是一件很麻煩的事情。我提供的解決方案是:

  • ... not use regexes, which should make the code more readable, maintainable, yada yada yada :)
  • …不使用regexes,這會使代碼更加可讀、可維護,yada yada yada yada:)
  • ... not check if a value contains pipes |, which will trip up this thing. On the other hand, a value may safely contain colons.
  • …不檢查一個值是否包含管道|,這會使這個東西出錯。另一方面,一個值可以安全地包含冒號。
  • ... not deal with multi-byte characters.
  • …不處理多字節字符。
  • ... not care about performance.
  • …不關心的性能。
  • ... assume the key "file" is always present.
  • …假設鍵“file”始終存在。
  • ... not insert missing keys, which should be dealt elsewhere in that case.
  • …不要插入缺失的鍵,在這種情況下,應該在其他地方處理。

Take these notes into consideration before blindly copy/pasting! ;)

在盲目復制/粘貼之前,要考慮到這些要點!,)

In addition, my solution contains the file-name in each element, which is redundant. But removing it would have made the solution messier without much gained value.

此外,我的解決方案在每個元素中包含文件名稱,這是多余的。但是去除它會使解決方案變得更混亂而沒有太多的價值。

Here's a solution:

這里有一個解決方案:

<?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"));

#2


1  

The following should do the trick.

下面的技巧應該很有用。

$rows = array();

foreach (preg_split('#\n#', file_get_contents('blah.txt')) as $line) {
  if (preg_match_all('#([^"|]+)\s*:\s*([^|]+)#', $line, $parts)) {
    $properties = array_map('trim', $parts[1]);
    $values = array_map('trim', $parts[2]);

    assert(count($properties) == count($values));

    $row = array();
    foreach ($properties as $index => $propertyName) {
      $row[$propertyName] = $values[$index];
    }
    $rows[] = $row;
  }
}

var_dump($rows);

#3


-1  

Try:

試一試:

$new_array = array();
while (($data = fgetcsv($csvfile, 1000, ";")) !== FALSE) {
    $new_array[$data[0]] = array('title' => $data[1], 'description' => $data[2], 'crop' => $data[3]);
}

var_dump($new_array);

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2014/03/03/729c1af7c34dfd47082b11ecba07a155.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com