2013-05-23 17 views
209

Mam plik parametru formularzaPython string.replace wyrażenie regularne

parameter-name parameter-value 

gdzie parametry mogą być w dowolnej kolejności, ale jest tylko jeden parametr w wierszu. Chcę zastąpić parametr-wartość parametru jedną nową wartością.

Używam funkcji zastąpienia linii wcześniej (Search and replace a line in a file in Python), aby zastąpić linię, która korzysta z Pythona string.replace (wzór, subst). Wyrażenie regularne, którego używam działa na przykład w vimie, ale nie działa w string.replace. Tutaj jest wyrażenie regularne, które używam:

line.replace("^.*interfaceOpDataFile.*$/i", "interfaceOpDataFile %s" % (fileIn)) 

gdzie interfaceOpDataFile jest nazwą parametru, że jestem zastępując (/ I dla przypadku niewrażliwe) i nowa wartość parametru jest zawartość zmiennej fileIn. Czy istnieje sposób, aby Pythona rozpoznać wyrażenie regularne, czy istnieje inny sposób na wykonanie tego zadania? Z góry dziękuję.

Odpowiedz

310

str.replace()v2 | v3 nie rozpoznaje wyrażeń regularnych.

Aby dokonać zamiany za pomocą wyrażenia regularnego, użyj re.sub()v2 | v3.

Na przykład:

import re 

line = re.sub(
      r"(?i)^.*interfaceOpDataFile.*$", 
      "interfaceOpDataFile %s" % fileIn, 
      line 
     ) 

w pętli, to byłoby lepiej najpierw skompilować wyrażenia regularnego:

import re 

regex = re.compile(r"^.*interfaceOpDataFile.*$", re.IGNORECASE) 
for line in some_file: 
    line = regex.sub("interfaceOpDataFile %s" % fileIn, line) 
    # do something with the updated line 
+19

Korzystanie skompilować poza pętlą jest świetne porady, ładne niuans tam - dzięki. – pokero

+3

Musiałem przekazać w 'flags = re.MULTILINE' jako ostatni argument do' re.sub', aby to działało, co ma sens - [przeczytaj o tym w dokumentacji tutaj] (https: // docs .python.org/2/library/re.html # re.MULTILINE) – tobek

+2

Kompilacje regex są buforowane ([docs] (https://docs.python.org/3.6/library/re.html#re.compile)) , więc kompilacja nie jest nawet konieczna. Ale jak pokazujesz, jeśli kompilujesz, kompiluj poza pętlą. – alttag

188

Szukasz funkcji re.sub.

import re 
s = "Example String" 
replaced = re.sub('[ES]', 'a', s) 
print replaced 

wypisze axample atring

8

re.sub jest na pewno to, czego szukasz. A więc wiesz, że nie potrzebujesz kotwic i symboli wieloznacznych.

re.sub(r"(?i)interfaceOpDataFile", "interfaceOpDataFile %s" % filein, line) 

zrobi to samo - pierwszy pasujący podciąg, który wygląda jak „interfaceOpDataFile” i zastąpienie go.

+0

muszę wymienić całą linię, ponieważ oryginalny plik będzie miał coś takiego: 'interfaceOpDataFile SomeDummyFile.txt' i chcę go zastąpić: ' interfaceOpDataFile SomeUsefulFile.txt' Jeśli nie dołączę kotwic, jak zastąpić, wiem, że chcę pozbyć się 'SomeDummyFile.txt'? –

+0

Ah, źle zrozumiałem, co robiłeś z wymianą. Jeśli każda para jest na osobnej linii, nadal nie potrzebujesz wyraźnej kotwicy. 're.sub (r" (? i) (interfaceOpDataFile). * ", r '\ 1 UsefulFile', line)' To zajmie całą linię, uchwyci nazwę argumentu i doda ją do podstawienia dla ciebie. – Nelz11

7

Jako podsumowanie

import sys 
import re 

f = sys.argv[1] 
find = sys.argv[2] 
replace = sys.argv[3] 
with open (f, "r") as myfile: 
    s=myfile.read() 
ret = re.sub(find,replace, s) # <<< This is where the magic happens 
print ret