2010-12-20 18 views
8

Mam ciąg znaków, który może wyglądać następującopython wyrażenie regularne zastąpienie części dopasowanej ciąg

"myFunc('element','node','elementVersion','ext',12,0,0)" 

Jestem obecnie sprawdzanie ważności użyciem, co działa dobrze

myFunc\((.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\) 

teraz jestem Chciałbym zastąpić dowolny ciąg na trzecim parametrze. Niestety nie mogę po prostu użyć stringreplace na cokolwiek pod-ciągu na trzeciej pozycji, ponieważ ten sam "pod-ciąg" może być gdziekolwiek indziej w tym ciągu.

z tym i na re.findall,

myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\) 

I był w stanie uzyskać zawartość podciągu na 3. pozycji, ale re.sub nie zastępuje ciąg po prostu zwraca mi łańcuch i chce wymienić:/

oto mój kod

myRe = re.compile(r"myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\)") 
val = "myFunc('element','node','elementVersion','ext',12,0,0)" 

print myRe.findall(val) 
print myRe.sub("noVersion",val) 

jakiś pomysł co Tęskniłam?

dziękuję! Seb

+2

Różnorodność odpowiedzi tutaj prowadzi mnie do przypuszczenia, że ​​rewolta pythonowy przeciwko Perl TIMTOWTDI motto było nieco błędne. :) –

Odpowiedz

1

Jeśli chcesz to zrobić bez użycia wyrażenia regularnego:

>>> s = "myFunc('element','node','elementVersion','ext',12,0,0)" 
>>> l = s.split(",") 
>>> l[2]="'noVersion'" 
>>> s = ",".join(l) 
>>> s 
"myFunc('element','node','noVersion','ext',12,0,0)" 
+1

co jeśli pierwszy argument to "ele, ment"? –

+3

Następnie wszystkie odpowiedzi, w tym wyrażenia regularne, kończą się niepowodzeniem. :) – dheerosaur

+0

masz rację! dlatego uważam, że parser najlepiej nadaje się do tego zadania niż wyrażenie regularne. –

7

W re.sub, trzeba podać substytucję dla całej dopasowania ciąg. Oznacza to, że musisz powtórzyć części, których nie chcesz zastąpić. To działa:

myRe = re.compile(r"(myFunc\(.+?\,.+?\,)(.+?)(\,.+?\,.+?\,.+?\,.+?\))") 
print myRe.sub(r'\1"noversion"\3', val) 
3

Jeśli Twoim jedynym narzędziem jest młotek, wszystkie problemy wyglądają jak paznokcie. Wyrażenie regularne jest potężnym młotkiem, ale nie jest najlepszym narzędziem do każdego zadania.

Niektóre zadania są lepiej obsługiwane przez analizator składni. W tym przypadku lista argument ciąg jest jak krotki Python, sou można oszukać: użyj wbudowanego parsera Pythona:

>>> strdata = "myFunc('element','node','elementVersion','ext',12,0,0)" 
>>> args = re.search(r'\(([^\)]+)\)', strdata).group(1) 
>>> eval(args) 
('element', 'node', 'elementVersion', 'ext', 12, 0, 0) 

Jeżeli nie można ufać wejście ast.literal_eval jest bezpieczniejszy niż eval do tego. Gdy masz już listę argumentów w dekontrukcji, myślę, że możesz wymyślić, jak w razie potrzeby manipulować i ponownie złożyć ją ponownie.

2

Przeczytaj dokumentację: zwraca kopię ciągu, w której każde wystąpienie całego wzoru jest zastępowane zamiennikiem. W żadnym wypadku nie można zmodyfikować oryginalnego ciągu, ponieważ ciągi w języku Python są niezmienne.

Spróbuj użyć wygląd światło i wyglądają-za twierdzeniami skonstruować regex, który pasuje tylko do samego elementu:

myRe = re.compile(r"(?<=myFunc\(.+?\,.+?\,)(.+?)(?=\,.+?\,.+?\,.+?\,.+?\))") 
+1

Jeśli istnieje szansa na argument zawierający przecinek, podejście do regex staje się coraz trudniejsze. –

Powiązane problemy