根据前面的行更改文件中的行 - Python

时间:2015-04-07 21:56:55

标签: python python-2.7

相对较新的python,试图找出解决此问题的最通用和可读的方法。执行速度也不会差,但它是次要问题。

我有另一个程序的输入文件,我需要自动编辑。格式类似于以下内容:

---Thousands of lines that can be ignored---
&Brand: Ford
&Define Class
&Model: Sedan
&Parameter: Cost
&Dollars
&25000
&Parameter: Stock
&Quantity
&14

&Brand: Honda
&Define Class
&Model: Sedan
&Parameter: Cost
&Dollars
&22000
&Parameter: Stock
&Quantity
&17
&Model: SUV
&Parameter: Cost
&Dollars
&35000
&Parameter: Stock
&Quantity
&7
---Thousands of lines that can be ignored---

我的代码需要自动更改数值参数。我遇到的麻烦是,我不只是匹配单个条件并改变一条线,我匹配非独特线的独特组合(参数:成本出现三次,两次出现在Model:Sedan下,两次出现在Brand下:本田,但在这两种条件下只有一次)。

正确我将新参数存储在嵌套字典中,例如:

params = {'Ford': {'Sedan': {'Cost': 17000, 'Stock': 43}}, 'Honda':{'Sedan': {'Cost': 19000, 'Stock': 12}, {'Truck': {'Cost': 33000, 'Stock': 5}}}

通过这种方式,我可以for brand in params.keys()然后for model in params[brand].keys()等等。

我有打开,关闭和修改文件的基础知识,它正在识别要修改的正确行,我遇到了麻烦。谢谢你的帮助。

例: 对于上面的示例字典,理想的输出是:

---Thousands of lines that can be ignored---
&Brand: Ford
&Define Class
&Model: Sedan
&Parameter: Cost
&Dollars
&17000
&Parameter: Stock
&Quantity
&43

&Brand: Honda
&Define Class
&Model: Sedan
&Parameter: Cost
&Dollars
&19000
&Parameter: Stock
&Quantity
&12
&Model: SUV
&Parameter: Cost
&Dollars
&33000
&Parameter: Stock
&Quantity
&5
---Thousands of lines that can be ignored---

4 个答案:

答案 0 :(得分:1)

必须查看Python的正则表达式?看看''包。您可以使用它来搜索数字条目。你可以像这样识别感兴趣的行(从我的头顶而不是检查):

import re
...
m = re.match(r'&(\d+)', the_line)
if m:
    print 'found ', m.group(1)
    # modify it...

表达式匹配任意数量的数字(\ d +部分)。不确定是否&很特别,但如果是,你可以放在方括号内。

当然,您需要类似的正则表达式来捕获之前的行是成本,然后捕获该值。你可以用一个简单的标志来做到这一点,信号网络是成本。

请参阅https://docs.python.org/2/library/re.html

答案 1 :(得分:1)

您可以阅读第while\n\n

import re
model=''
brand=''
whit open('old_file') as f1,open('out_file','w') as f2:

    for line in f1:
          while line !='\n\n':
                if 'Brand' in line :
                    brand=re.match(r'&Brand:(.*)',line).group(1)
                    f2.write(line)
                elif 'Model' in line:
                    model=re.match(r'&Model:(.*)',line).group(1)
                    f2.write(line)

                elif model and brand:
                      if line.strip('&')=='Dollars':
                            f2.write('Dollars'+'\n'+params[brand.strip()][model.strip()]['Cost'])
                      elif line.strip('&')=='Quantity':
                            f2.write('Dollars'+'\n'+params[brand.strip()][model.strip()]['Stock'])

                else:
                      f2.write(line)

答案 2 :(得分:1)

这样的事可能有用。我创建了一个生成器,然后您可以迭代以编写更新的文件。

def get_lines(dic):
    brand = ''
    model = ''
    parameter = ''
    with open('testinput.txt', 'r') as fil:
        for line in fil:
            if line[1:].strip().isdigit() and brand in dic and model in dic[brand] and parameter in dic[brand][model]:
                yield '&{0}\n'.format(dic[brand][model][parameter])
            elif line.startswith('&Brand:'):
                brand = line.split(': ')[-1].strip()
                yield line
            elif line.startswith('&Model:'):
                model= line.split(': ')[-1].strip()
                yield line
            elif line.startswith('&Parameter:'):
                parameter= line.split(': ')[-1].strip()
                yield line
            else:
                yield line

params = {'Ford': {'Sedan': {'Cost': 17000, 'Stock': 43}}, 'Honda':{'Sedan': {'Cost': 19000, 'Stock': 12}, 'Truck': {'Cost': 33000, 'Stock': 5}}}

with open('output.txt', 'w') as fil:
    for line in get_lines(params):
        fil.write(line)

答案 3 :(得分:0)

import re,fileinput
def print_new_data(brand,model,data):
    print "&Brand: %s"%(brand)
    print "&Define Class"
    print "&Model: %s"%(model)
    print "&Parameter: Cost"
    print "&Dollars"
    print "&%s"%data["cost"]
    print "&Parameter: Stock"
    print "&Quantity"
    print "&%s\n"%data["stock"]        

def process(fh):
    line = next(fh)
    brand= re.findall("Brand: (.*)",line)
    if not brand or brand[0] not in my_list_of_brands::
       print line
       return
    brand = brand[0]
    junk = next(fh)
    model_line = next(fh)
    model_name = re.findall("Model: (.*)",model_line)[0]
    if model_name not in my_data[brand]:
       print line
       print junk
       print model_line
       return
    while line.strip():
       next(fh)
    print_new_data(brand,model,my_data[brand][model])


fh = fileinput.open(["my_data_file"],inplace=1):
while True:
    process(fh)
......我不敢相信我浪费了多少时间为你做这件事......