在某些情况下,将文本文件中的输入内容用regex读成字典。

问题描述 投票:0回答:1

所以我想从一个 input.txt 文件,创建一个字典

例如,这里是示例的 input.txt 档案

%. VAR %first=Billy
%. VAR %last=Bob
%. PRINT VARS
%. VAR %petName=Gato
%. VAR %street="1234 Home Street"
%. VAR %city="New York" 
%. VAR %state=NY 
%. VAR %zip=21236 
%. VAR %title=Dr.
%. PRINT VARS
%. FORMAT LM=5  JUST=LEFT
%. PRINT FORMAT

所以 VAR %varName=value

即在 %first=Billy 你会得到这样的东西 varDict = {"first": "Billy"} 现在我想知道如何做到这一点,通过整个文件的

我需要填充两个字典,一个是变量的,一个是FORMAT的,FORMAT只是保存值,暂时没有实际作用。

至于想要的输出,我想的是这样的方式,我会使用pprint函数,比如说 pprint.pprint(varDict , width=30) 并将输出类似这样的东西

{'first': 'Billy',
'last': 'Bob'}
{'city': 'New York',
'first': 'Billy',
 'last': 'Bob',
'petName': 'Gato',
'state': 'NY',
'street': '1234 Home Street',
'title': 'Dr.',
'zip': '21236'}
{'BULLET': 'o',
'FLOW': 'YES',
'JUST': 'LEFT',
'LM': '5',
'RM': '80'}

编辑

我现在要把我的代码输入到我的 setFormatWIP.py

import re
import sys
import pprint

input=(sys.argv[1])

regexFormat = re.compile(r'^%\.\s*?FORMAT\s*?((?:(?:\w+)=(?:\w+)\s*)*)$', re.MULTILINE)
regexPrintFORMAT = re.compile(r'^%\.\s*PRINT\s(FORMAT)',re.MULTILINE)

file = open(input)
line = file.readline()
formatDict = dict()

while line:
    formatList = regexFormat.findall(line)
    printFormatObj = regexPrintFORMAT.search(line)
    if printFormatObj != None:
            pprint.pprint(formatDict, width=30)
    for param in formatList[0].split():
        splitParam = param.split('=')
        formatDict[splitParam[0]] = splitParam[1]

    line = file.readline()
file.close()

运行该程序,我得到这个错误

Traceback (most recent call last):
File "formatTest.py", line 19, in <module>
for param in formatList[0].split():
IndexError: list index out of range
python regex python-3.x dictionary associative-array
1个回答
1
投票

你的主要问题似乎是关于使用正则表达式。re.findall相当简单。它返回一个包含你的表达式所找到的值的列表。

import re

lines = [
    "%. VAR     %first=Billy",
    "%. VAR     %last=Bob",
    "%. PRINT VARS",
    "%. VAR     %petName=Gato",
    "%. VAR     %street=\"1234 Home Street\"",
    "%. VAR     %city=\"New York\" ",
    "%. VAR     %state=NY ",
    "%. VAR     %zip=21236 ",
    "%. VAR     %title=Dr.",
    "%. PRINT VARS",
    "%. FORMAT LM=5  JUST=LEFT",
    "%. PRINT FORMAT",
    ]

# find VAR
re_VAR = r'^\%\.\s+VAR\s+%'
VAR_list = []
for line in lines:
    re_result = re.findall(re_VAR, line)
    if re_result:
        text = line.replace(re_result[0], '')
        text_parts = text.split('=')
        VAR_list.append({text_parts[0]: text_parts[1]})

print(VAR_list)

结果是

[{'first': 'Billy'}, {'last': 'Bob'}, {'petName': 'Gato'}, {'street': '"1234 Home Street"'}, {'city': '"New York" '}, {'state': 'NY '}, {'zip': '21236 '}, {'title': 'Dr.'}]

你可以在这里测试你的正则表达式 regex101.com


1
投票

如果你能把整个文件读成一个字符串,那么下面的表达式应该能检索到你所有的变量。

import re

var_pat = re.compile(r'^%\.\s*?VAR\s*?%(\w+)=(\w+|".*")\s*$', re.MULTILINE)
with open('input.txt') as f:
    text = f.read()

var_list = var_pat.findall(text)
print(var_list)
[('first', 'Billy'), ('last', 'Bob'), ('petName', 'Gato'), ('street', '"1234 Home Street"'), ('city', '"New York"'), ('state', 'NY'), ('zip', '21236')]

然后你就可以做这样的事情来获取你的字典。

var_dict = dict()
for k, v in var_list:
    var_dict[k] = v

对于格式模式,这个

format_pat = re.compile(r'^%\.\s*?FORMAT\s*?((?:(?:\w+)=(?:\w+)\s*)*)$', re.MULTILINE)
format = format_pat.findall(text)
print(format)

会产生

['LM=5  JUST=LEFT']

所以你可以通过做来获得你的dict。

format_dict = dict()
for param in format[0].split():
    split_param = param.split('=')
    format_dict[split_param[0]] = split_param[1]
print(format_dict)
{'LM': '5', 'JUST': 'LEFT'}

你可以在Mace发布的链接上了解这些regexes.


编辑

为了得到所需的输出--不需要一次搜索所有的VAR,只需要迭代文件的行,并尝试将每个模式与该行进行匹配,然后根据其匹配度处理该行。

var_dict = {}
with open('input.txt', 'r') as f:
    for line in f:
        m_var = var_pat.match(line)
        if m_var:
            var_dict[m_var.group(1)] = m_var.group(2)
            continue
        m_print = print_pat.match(line)
        if m_print:
            pprint.pprint(var_dict, width=30)
        .
        .
        .

Where print_pat 是一个与该行相匹配的regex模式。PRINT VARS. 你可以阅读更多关于Python regex函数的信息,如 re.match() 此处.

© www.soinside.com 2019 - 2024. All rights reserved.