簡體   English   中英

Python:如何解析和添加內容到文本文件

[英]Python: how to parse and and add contents to a text file

您好,我有一個特定格式的網絡,即.gdf 但是,這是一個以下格式的文本文件

network:
nodedef>name VARCHAR,label VARCHAR
0,' 0 '
1,' 1 '
2,' 2 '
edgedef>node1 VARCHAR,node2 VARCHAR,weight DOUBLE
0,1,0.2
0,2,0.2
0,3,0.2
0,4,0.333333

第一部分引用節點,第二部分引用邊緣。

我想添加功能來讀取文件並向節點添加功能並返回以下內容:

network:
nodedef>name VARCHAR,label VARCHAR, att1 VARCHAR
0,' 0 ', 'Paul'
1,' 1 ', 'Jack'
2,' 2 ', 'John'
edgedef>node1 VARCHAR,node2 VARCHAR,weight DOUBLE
0,1,0.2
0,2,0.2
0,3,0.2
0,4,0.333333

以下是一些代碼,用於執行您要求的上半部分。 它將解析.GDF文件並使您可以獲得信息。 添加屬性並編寫它們留給讀者練習。

import ast
import collections
import re


def main():
    parser = GDFParser()
    with open('network.gdf') as file:
        parser.read(file)
    print(*parser.data, sep='\n')


def pivot(iterable):
    columns = []
    for row in iterable:
        columns.extend([] for _ in range(len(row) - len(columns)))
        for column, cell in zip(columns, row):
            column.append(cell)
    return columns


class GDFParser:

    HEADER = re.compile('\w+:')
    DEF = re.compile('\w+>\w+ (?:DOUBLE|VARCHAR)(?:,\w+ (?:DOUBLE|VARCHAR))*')
    CAST = dict(DOUBLE=float, VARCHAR=str)

    def __init__(self):
        self.__header = None
        self.__type = []
        self.__data = []

    @property
    def header(self):
        return self.__header

    @property
    def data(self):
        return tuple(self.__data)

    def read(self, file):
        for line in file:
            self.__read_line(line.strip())

    def __read_line(self, line):
        if self.HEADER.fullmatch(line):
            self.__process_header(line)
        elif self.DEF.fullmatch(line):
            self.__process_def(line)
        else:
            self.__process_data(line)

    def __process_header(self, line):
        if self.header:
            raise ValueError('header was previously set')
        self.__header = line[:-1]

    def __process_def(self, line):
        name, fields = line.split('>')
        columns, casts = pivot(field.split() for field in fields.split(','))
        self.__type.append((collections.namedtuple(name, columns),
                            tuple(map(self.CAST.__getitem__, casts))))

    def __process_data(self, line):
        if not self.__type:
            raise ValueError('a definition must come before its data')
        kind, casts = self.__type[-1]
        self.__data.append(kind(*(cast(item) for cast, item in
                                  zip(casts, ast.literal_eval(line)))))


if __name__ == '__main__':
    main()

暫無
暫無

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

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