簡體   English   中英

PHP-遍歷文件並為JSON分解大量文本

[英]PHP - Iterate through file and break out chunks of text for JSON

我在服務器上有一個文件,需要解析並構建一個JSON對象以返回。 我正在使用PHP。

文件內容如下所示:

########################################
#             NOTES FILE
#
# THIS FILE IS AUTOMATICALLY GENERATED
#        DO NOT MODIFY THIS FILE!
########################################

info {
    created=1552596653
    version=4.4.3
    last_update_check=1552554585
    update_available=0
    last_version=4.4.3
    new_version=4.4.3
    }

programstatus {
    modified_host_attributes=0
    modified_service_attributes=0
    pid=11523
    daemon_mode=1
    program_start=1552593834
    last_log_rotation=0
    ...

理想情況下,我想抓取每個段(例如:“ info”,“ programstatus”等),然后將其添加到我通過它解析的JSON obj / array中。 每個attribute = value分配。

所以像這樣:

$data = array();

// Loop here for each segment
$data['info'] = array(
    "created" => "1552596653",
    "version" => "4.4.3",
    etc...
)

// Then wrap it up with something like
return json_encode($data);

我只是無法“想”在將文件分成幾塊時循環瀏覽。

我通過以下方式獲得文件內容:

$statusFile = '/location/to/my/data/file';

ob_start();
include( $statusFile );
$statusFileContent = ob_get_contents();
ob_end_clean();

我為您提供了一個優雅的解決方案。 您不需要循環,只需執行5行代碼即可。 只需使用正則表達式並轉換您擁有的文件即可。

$file = "Your file as a string";

//Get the titles like 'info' and put it around quotion marks
$titles_changed = preg_replace('/(.*)\{/', '"$1":{', $file, -1 );

//Get strings like created=1552596653 and transform to "created"="1552596653",
$values_changed = preg_replace('/(.*)=(.*)/', '"$1":"$2",', $titles_changed );

//Remove spaces from the string
$no_spaces = preg_replace('/\s/s', '', $values_changed);

//Fix all that became ",}" from the second replacement and transforms it into "},"
$limits_fixed = preg_replace('/\,\}/', '},', $no_spaces);

//Remove a "," that lasts on the end of the file and put all string around brakets
$json = "{". rtrim($limits_fixed, ',') . "}";

$object = json_decode($json);

您需要完成3件事:

  1. 以一種允許您讀取非常大的文件的方式加載文件內容,而無需將其完全存儲在內存中。
  2. 獲取每一行時,您需要通過自己設計的解析算法來運行它,以便能夠有效地提取數據。
  3. 最后,您需要將每一行的數據寫入內存(如果您希望數據過大並可能用完,則將其寫入文件)。

這是我匯總的一小段代碼,它們說明了您可以采用的方法。 我在PHP Fiddle上進行了測試,但無法弄清楚如何共享鏈接。

<?php

    // File path to load
    // $file = "/path/to/file.txt";
    $file = "https://pastebin.com/raw/gu2AC7qy";

    // Flag indicating we are inside of a "block"
    $inBlock = false;

    // Name/Key of current "block"
    $blockName = null;

    // Container for our data
    $data = [];

    // Open for reading
    $handle = fopen($file, 'r');

    // If we opened it (you should add better error handling)
    if ($handle) {

        // Grab each line one at a time
        while(($line = fgets($handle)) !== false) {

            // Cleanup line
            $line = trim($line);

            // Throw away useless lines (comments, empty, etc.)
            if (empty($line)) {
                // Skip blank lines
                continue;
            }
            if (substr($line, 1) == '#') {
                // Skip comments
                continue;
            }

            // Check if start of "block"
            if (substr($line, -1) == '{') {
                // Set the flag
                $inBlock = true;
                // Get the block name
                $blockName = trim(str_replace('{', '', $line));
                // Create new data section
                $data[$blockName] = [];
                // Get next line
                continue;
            }

            // If currently inside block
            if ($inBlock === true && ! empty($blockName)) {
                // Get a data attribute
                $dataRow = trim($line);
                // Parse as key/value
                $dataRowParts = explode("=", $dataRow);
                $key = isset($dataRowParts[0]) ? trim($dataRowParts[0]) : null;
                $value = isset($dataRowParts[1]) ? trim($dataRowParts[1]) : "";
                // Store in current block's data
                if ($key !== null) {
                    $data[$blockName][$key] = $value;
                }
                // Get next line
                continue;
            }

            // Check if end of "block"
            if (substr($line, -1) == '}') {
                // Clear flag
                $inBlock = false;
                // Unset block name
                $blockName = null;
                // Get next line 
                continue;
            }
        }

        // Close the file
        fclose($handle);
    }

    // Output data as JSON
    echo json_encode($data);

?>

理想情況下,您應該將此邏輯放在類和方法中,這樣就不會有太多的代碼了—當然要添加適當的錯誤處理。 祝好運!

您可以利用以下事實:這幾乎是一個.ini文件。

刪除頂部,將括號中的組轉換為ini部分

$sections = preg_replace(['/#.*/', '/(\S+) \{/', '/}/'], ['', '[$1]', ''], $file_contents);

然后是一個.ini字符串。

$result = parse_ini_string($sections, true);

echo json_encode($result);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM