[英]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.