2012-12-27 17 views
7

Sto creando una classe che rinomina un file utilizzando un formato specificato dall'utente. Questo formato sarà una semplice stringa il cui metodo str.format verrà chiamato per riempire gli spazi vuoti.Come posso trovare tutti i segnaposto per str.format in una stringa python usando un'espressione regolare?

Si scopre che la mia procedura richiederà l'estrazione di nomi di variabili contenuti in parentesi graffe. Ad esempio, una stringa può contenere {user}, che dovrebbe produrre user. Naturalmente, ci saranno diverse serie di parentesi graffe in una singola stringa, e avrò bisogno di ottenere il contenuto di ciascuna, nell'ordine in cui appaiono e di inviarle ad una lista.

Pertanto, "{foo}{bar}" deve produrre ['foo', 'bar'].

Ho il sospetto che il modo più semplice per farlo sia utilizzare re.split, ma non so nulla delle espressioni regolari. Qualcuno mi può aiutare?

Grazie in anticipo!

+0

Se si conoscono tutte le variabili possibili * in anticipo *, si può passare semplicemente t orlo tutto a 'str.format' - ignorerà quelli non in pattern. ''{utente} _ {bar}'. format (utente = 'Mike', foo = 1, bar = 2)' produrrà 'Mike_2'. Ho avuto la fortuna di aver permesso alle vars fisse in un dict, così ho potuto saltare cercando vars in pattern. In ogni caso, conoscere 'string.Formatter()' è utile. – yentsun

risposta

12

Utilizzando 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

Solo una domanda veloce. I risultati di 're.findall' sono garantiti per essere elencati nello stesso ordine in cui appaiono nella stringa? – blz

+1

@blz yes, poiché la stringa viene analizzata da sinistra a destra. –

37

Un'altra possibilità è quella di utilizzare Python di effettiva Formatter sé per estrarre i nomi dei campi per voi:

>>> 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'] 

o (più breve, ma meno informativo):

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

oooooh ... Mi piace! Probabilmente accetterò la risposta di Ashwini Chaudhary perché ho chiesto specificamente una soluzione regex, ma penso che userò la tua poiché la capisco un po 'meglio! Grazie! – blz

Problemi correlati