2015-01-09 5 views
0

사전에 일치하는 키와 관련된 색인을 포함하는 스크립트가 있습니다. 최근의 변경으로 모든 숫자를 1 이상으로 이동해야합니다 (각 숫자에 1을 더함). 예를 들어 파일에 다음 내용이 포함 된 경우 :파이썬 : 파일의 모든 정수에 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

당신은'='당신의 예제 파일 등호를 넣고'콜론을 사용'스크립트에서. 나는 틀린 하나라고 생각한다. 그러나 그것은 어느 쪽 이냐? 그리고 정수가 항상 괄호 안에 들어 있으며 목록은 항상 한 줄로되어 있는지 확인할 수 있습니까? –

+0

그들은 콜론이어야합니다. 죄송합니다. 각 키는 목록 또는 숫자 중 하나가되는 고유 한 키입니다. 또한 목록이 반드시 같은 줄에있는 것은 아닙니다. 좋은 지적입니다. – user2869231

+2

이 데이터는 JSONish로 보입니다. 신속하고 더러운 regexes의 바깥쪽에는 "적절한"해결책이 파서를 실행하거나 작성하여 데이터를 구조화 한 다음 변경된 후에 다시 작성하는 것보다 낫습니다. –

답변

4

형식을 유지하고 형식을 변경하지 말고 (예 : 단어 경계로 구분 된 모든 정수) 형식을 유지하려면 간단한 정규식 검색/바꾸기가 필요합니다. 단어 경계 (\b), 임의의 연속 정수 (\d+) 및 종결 단어 경계 (\b). 이 'foo 15 bar', '[1]', '[1, 2]' 같은 문자열에 숫자를 증가하지만, 'foo15bar' 또는 'foo15'하지 : 내가 실행을 문자열로 s에 마지막 줄을 데이터를 할당하는 경우

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) 

, 내가 얻을 :

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

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

당신이 원하는 것 같습니다. 물론 숫자를 증가시키지 않으려는 경우이 방법은 효과가 없습니다. 파일을 구문 분석하는 더 똑똑한 방법이 필요합니다.

+0

잘 작동합니다. 그래도 정확히 무슨 일이 일어 났는지 설명해 주시겠습니까? hehe 나는 정규 표현식을 손으로 작업 해 왔지만 코드에서 실제로 정규 표현식을 구현 한 적이 없다. 아직도, 람다는 나에게 무슨 짓을하는지 prob 다. – user2869231

+0

아, 편집은 그 일을 잘 수행했습니다. 감사! 도움을 주신 덕분에 – user2869231

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

+1

숫자가 증가하는 데 좀 더 민감해야 할 필요가 있다면 mgilson의 접근 방식에 대한 훌륭한 대안입니다. –

+0

흠. 이것이 5보다 더 큰 값만 증가 시키려고한다면 이것은 일종의 일이 될까요? – user2869231

관련 문제