2015-01-09 58 views
0

我有一个脚本,其中包含与字典中的匹配键有关的索引。最近的更改要求我将所有数字都转换为1(每个数字加1)。例如,如果文件包含以下内容:Python:如何将1添加到文件中的每个整数

form['formA'] = { 
    'title': 'titleA', 
    'number': 3, 
    'numbers': [1,2,4,5] 
} 

form['formB'] = { 
    'title': 'titleB', 
    'number': 7, 
    'numbers': [8,9,10,11] 
} 

我希望每个整数都是一个更大的整数。因此,这将成为:

form['formA'] = { 
    'title': 'titleA', 
    'number': 4, 
    'numbers': [2,3,5,6] 
} 

form['formB'] = { 
    'title': 'titleB', 
    'number': 8, 
    'numbers': [9,10,11,12] 
} 

所有类型的错误之间,属性错误,只是销毁的格式,我无法弄清楚如何做到这一点。这可能是我最接近的尝试:

#read from the file 
f = open(currdir, 'r') 
content = f.readlines() 
f.close() 

addbrackets = False #is it a list 
for line in content: 
    if "form" not in line: 
     #grab only the values to the right of the colon 
     rightside = line.split(":")[-1] 
     list_of_nums = rightside 

     #remove brackets 
     if "[" in rightside: 
      addbrackets = True 
      removebrackets = rightside.replace("[","").replace("]","") 
      list_of_nums = removebrackets.split(",") 

     #search for all integers in the list and add 1 
     for num in list_of_nums: 
      if type(num) is int: 
       num += 1 
       numindex = list_of_nums.index(num) 
       list_of_nums[numindex] = num 

     #plug new values into content 
     lineindex = content.index(line) 
     if addbrackets: 
      content[lineindex] = line.replace(rightside, "[" + ",".join(list_of_nums))[:-1] + "]," 
      addbrackets = False 
     else: 
      content[lineindex] = line.replace(rightside, "".join(list_of_nums)) 

#write to the new file 
f = open(newdir, 'w') 
f.write("".join(content)) 
f.close() 

但是,这只是设法弄乱格式。有没有办法做到这一点?

谢谢。

+0

你把等号'='在您例如文件,并使用冒号':'在你的脚本。我猜想有一个错误,但是哪一个?你能确定整数总是在括号内,并且列表总是在一行中? – 2015-01-09 18:24:04

+0

他们应该是冒号,对此感到抱歉。每个密钥对于列表或数字都是唯一的。此外,名单不一定在同一行 - 好点。 – user2869231 2015-01-09 18:34:33

+2

该数据看起来像JSONish。在快速和肮脏的正则表达式之外回答如下:“正确的”解决方案很可能运行或编写解析器来构造数据,然后在更改后将其写回。 – 2015-01-09 18:40:02

回答

4

如果你确实想要保持格式化,并且想要对你重新格式化的内容(例如,所有用边界分隔的整数)不加区分,那么这是一个简单的正则表达式搜索/替换,你需要搜索一个字边界(\b),任意数量的连续整数(\d+),然后是终止字边界(\b)。这将增加号码串像'foo 15 bar''[1]''[1, 2]',但不'foo15bar''foo15'

import re 
with open(yourfilename) as fin: 
    s = fin.read() 
print re.sub(r'\b\d+\b', lambda m: str(int(m.group())+1), s) 

如果我给你你的数据s为字符串的运行线下决赛,我得到:

form['formA'] = { 
    'title' = 'titleA', 
    'number' = 4, 
    'numbers' = [2,3,5,6] 
} 

form['formB'] = { 
    'title' = 'titleB', 
    'number' = 8, 
    'numbers' = [9,10,11,12] 
} 

这似乎是你想要的。当然,如果你有一些你不希望增加的数字,那么这将不起作用 - 你需要一个更聪明的方法来解析文件。

+0

那么工作。你能向我解释究竟发生了什么吗?呵呵我用手工处理过正则表达式,但从未在代码中实际实现过它们;尽管如此,拉姆达还是让我感到困惑的。 – user2869231 2015-01-09 18:39:23

+0

啊,你的编辑做得很好。谢谢! – user2869231 2015-01-09 18:40:19

2

使用正则表达式:

foo=""" 
form['formA'] = { 
    'title' = 'titleA', 
    'number' = 3, 
    'numbers' = [1,2,4,5] 
} 

form['formB'] = { 
    'title' = 'titleB', 
    'number' = 7, 
    'numbers' = [8,9,10,11] 
} 
""" 

def incNumbers(s): 
    def inc(m): 
    return str(int(m.group())+1) 
    return re.sub(r'(\d+)', inc, s) 


def go(m): 
    return m.group(1) + incNumbers(m.group(2)) 

r = re.compile('^(*\'numbers?\' =)(.*)', re.MULTILINE) 
print re.sub(r, go, foo) 
+0

感谢您的帮助!不过,mgilson已经知道了。 – user2869231 2015-01-09 18:41:31

+1

如果您需要对哪些数字增加更敏感一点,可以作为mgilson方法的一个很好的选择。 – 2015-01-09 18:41:40

+0

嗯。那么,如果我只想增加大于5的值,那么这种方法是行得通的吗? – user2869231 2015-01-09 18:45:56

相关问题