2013-01-05 10 views
7

Czy można wykonywać prostą matematykę na wyjściu z wyrażeń regularnych Python?Wykonaj prostą matematykę na wyjściu wyrażenia regularnego? (Python)

mam dużego pliku, gdy trzeba podzielić na następujące numery ")" przez 100. Na przykład, by konwertować zawierające następującą linię )75 i )2:

((words:0.23)75:0.55(morewords:0.1)2:0.55); 

do )0.75 i )0.02:

((words:0.23)0.75:0.55(morewords:0.1)0.02:0.55); 

Moja pierwsza myśl to użyć re.sub przy użyciu wyrażenia wyszukiwania "\)\d+", ale nie wiem, jak podzielić int eger podążając za nawiasami przez 100, lub jeśli jest to możliwe, używając re.

Wszelkie uwagi na temat rozwiązania tego problemu? Dzięki za pomoc!

+1

Czy próbowałeś przekonwertować ciąg na liczbę całkowitą? – erbridge

+0

Regex służy do manipulacji tekstem. Aby osiągnąć, nie widzę żadnej ucieczki od konwersji ciągu na liczbę całkowitą i dzielenia go przez 100. – andrefsp

+2

Nawiasem mówiąc, wygląda na to, że jest w formacie Newick (z wyjątkiem tego, że w formacie Newick normalnie nie miałbyś pewności co do bootstrapu pojedynczy węzeł, taki jak 'words' lub' morewords'). Możesz mieć łatwiejsze wykonywanie innych operacji za pomocą parsera Newick, np. [W BioPython] (http://biopython.org/DIST/docs/tutorial/Tutorial.html#htoc165), zamiast w regex. –

Odpowiedz

13

Można to zrobić poprzez dostarczenie funkcję jak Zamiennik:

s = "((words:0.23)75:0.55(morewords:0.1)2:0.55);" 

s = re.sub("\)(\d+)", lambda m: ")" + str(float(m.groups()[0])/100), s) 

print s 
# ((words:0.23)0.75:0.55(morewords:0.1)0.02:0.55); 

Nawiasem mówiąc, jeśli chcesz to zrobić za pomocą BioPython's Newick tree parser zamiast, to będzie wyglądać następująco:

from Bio import Phylo 
# assuming you want to read from a string rather than a file 
from StringIO import StringIO 

tree = Phylo.read(StringIO(s), "newick") 

for c in tree.get_nonterminals(): 
    if c.confidence != None: 
     c.confidence = c.confidence/100 

print tree.format("newick") 

(podczas ta konkretna operacja zajmuje więcej linii niż wersja regex, inne operacje obejmujące drzewa mogą być z nią znacznie łatwiejsze).

+0

Awesome, thanks !! Działa świetnie – chimeric

1

Zastępcze wyrażenie dla re.sub może być funkcją. Napisz funkcję, która pobiera dopasowany tekst, przekształca go na liczbę, dzieli go na 100, a następnie zwraca ciąg znaków wyniku.

Powiązane problemy