簡體   English   中英

解析冒號分隔的數據

[英]Parsing colon delimited data

我有以下文本塊:

string = """
    apples: 20
    oranges: 30
    ripe: yes
    farmers:
            elmer fudd
                   lives in tv
            farmer ted
                   lives close
            farmer bill
                   lives far
    selling: yes
    veggies:
            carrots
            potatoes
    """

我試圖找到一個好的正則表達式,使我能夠解析出關鍵值。 我可以用以下方法獲取單行鍵值:

'(.+?):\s(.+?)\n'

但是,問題出在我打農民或蔬菜時。

使用re標志,我需要執行以下操作:

re.findall( '(.+?):\s(.+?)\n', string, re.S), 

但是,我有一點時間來抓住與農民相關的所有價值。

每個值后都有一個換行符,值是多行時在它們之前有一個選項卡或一系列選項卡。

目標是擁有類似的東西:

{ 'apples': 20, 'farmers': ['elmer fudd', 'farmer ted'] }

等等

預先感謝您的幫助。

您可能會看PyYAML ,如果實際上不是有效的YAML,則此文本非常接近。

這是一種完全愚蠢的方法:

import collections


string = """
    apples: 20
    oranges: 30
    ripe: yes
    farmers:
            elmer fudd
                   lives in tv
            farmer ted
                   lives close
            farmer bill
                   lives far
    selling: yes
    veggies:
            carrots
            potatoes
    """


def funky_parse(inval):
    lines = inval.split("\n")
    items = collections.defaultdict(list)
    at_val = False
    key = ''
    val = ''
    last_indent = 0
    for j, line in enumerate(lines):
        indent = len(line) - len(line.lstrip())
        if j != 0 and at_val and indent > last_indent > 4:
            continue
        if j != 0 and ":" in line:
            if val:
                items[key].append(val.strip())
            at_val = False
            key = ''
        line = line.lstrip()
        for i, c in enumerate(line, 1):
            if at_val:
                val += c
            else:
                key += c
            if c == ':':
                at_val = True
            if i == len(line) and at_val and val:
                items[key].append(val.strip())
                val = ''
        last_indent = indent

    return items

print dict(funky_parse(string))

OUTPUT

{'farmers:': ['elmer fudd', 'farmer ted', 'farmer bill'], 'apples:': ['20'], 'veggies:': ['carrots', 'potatoes'], 'ripe:': ['yes'], 'oranges:': ['30'], 'selling:': ['yes']}

這是一個非常愚蠢的解析器,它考慮了您(明顯)的縮進規則:

def parse(s):
    d = {}
    lastkey = None
    for fullline in s:
        line = fullline.strip()
        if not line:
            pass
        elif ':' not in line:
            indent = len(fullline) - len(fullline.lstrip())
            if lastindent is None:
                lastindent = indent
            if lastindent == indent:
                lastval.append(line)
        else:
            if lastkey:
                d[lastkey] = lastval
                lastkey = None
            if line.endswith(':'):
                lastkey, lastval, lastindent = key, [], None
            else:
                key, _, value = line.partition(':')
                d[key] = value.strip()
    if lastkey:
        d[lastkey] = lastval
        lastkey = None
    return d

import pprint
pprint(parse(string.splitlines()))

輸出為:

{'apples': '20',
 'oranges': '30',
 'ripe': ['elmer fudd', 'farmer ted', 'farmer bill'],
 'selling': ['carrots', 'potatoes']}

我認為這已經足夠復雜,以至於作為一個顯式的狀態機看起來會更整潔,但是我想用任何新手都可以理解的術語來編寫。

暫無
暫無

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

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