2012-12-27 9 views
7

Tworzę klasę, która zmienia nazwę pliku przy użyciu formatu określonego przez użytkownika. Ten format będzie prostym łańcuchem, którego metoda zostanie wywołana, aby wypełnić puste pola.Jak mogę znaleźć wszystkie symbole zastępcze dla str.format w łańcuchu Pythona za pomocą wyrażenia regularnego?

Okazuje się, że moja procedura będzie wymagać wydobycia nazw zmiennych zawartych w nawiasach. Na przykład ciąg może zawierać {user}, co powinno dać user. Oczywiście będzie kilka zestawów nawiasów klamrowych w jednym ciągu, a ja będę musiał pobrać zawartość każdego z nich, w kolejności, w jakiej się pojawiają i wyprowadzić je do listy.

Zatem "{foo}{bar}" powinien dawać ['foo', 'bar'].

Podejrzewam, że najprostszym sposobem, aby to zrobić jest użycie re.split, ale ja nic o wyrażeniach regularnych znać. Czy ktoś może mi pomóc?

Z góry dziękuję!

+0

W przypadku znasz wszystkich możliwych zmiennych * wcześniej *, można po prostu przejść t zawęź wszystkie do "str.format" - zignoruje te nie we wzorcu. ''{user} _ {bar}'. format (użytkownik = 'Mike', foo = 1, bar = 2)' wypisze 'Mike_2'. Zdarzyło mi się, że pozwoliłem, aby vary zostały ustalone w dyktowaniu, więc mogłem pominąć szukanie wzorców. W każdym razie znajomość 'string.Formatter()' jest przydatna. – yentsun

Odpowiedz

12

Korzystanie re.findall():

In [5]: import re 

In [8]: strs = "{foo} spam eggs {bar}" 

In [9]: re.findall(r"{(\w+)}", strs) 
Out[9]: ['foo', 'bar'] 
+0

Po prostu szybkie pytanie. Czy wyniki "re.findall" są wymienione w kolejności, w jakiej pojawiają się w łańcuchu? – blz

+1

@blz tak, ponieważ łańcuch jest analizowany od lewej do prawej. –

37

Inną możliwością jest użycie Pythona rzeczywista sama Formatter wyodrębnić nazwy pól dla Ciebie:

>>> import string 
>>> s = "{foo} spam eggs {bar}" 
>>> string.Formatter().parse(s) 
<formatteriterator object at 0x101d17b98> 
>>> list(string.Formatter().parse(s)) 
[('', 'foo', '', None), (' spam eggs ', 'bar', '', None)] 
>>> field_names = [name for text, name, spec, conv in string.Formatter().parse(s)] 
>>> field_names 
['foo', 'bar'] 

lub (krótsze, ale mniej informacyjny):

>>> field_names = [v[1] for v in string.Formatter().parse(s)] 
>>> field_names 
['foo', 'bar'] 
+0

oooooh ... Podoba mi się to! Prawdopodobnie przyjmuję odpowiedź Ashwiniego Chaudhary'ego, ponieważ specjalnie poprosiłem o rozwiązanie regex, ale myślę, że wykorzystam twoje, ponieważ rozumiem to trochę lepiej! Dziękuję Ci! – blz

Powiązane problemy