2013-02-18 14 views
7

Ho un dittico di parole (in realtà, ho annidato dicte di coniugazioni di verbi, ma non è rilevante) e voglio fare un'espressione regolare combinandole.Come posso creare un'espressione regolare da un elenco di parole?

{ 
    'yo': 'hablaba', 
    'tú': 'hablabas', 
    'él': 'hablaba', 
    'nosotros': 'hablábamos', 
    'vosotros': 'hablabais', 
    'ellos': 'hablaban', 
    'vos': 'hablabas', 
} 

... per fare:

'habl((aba(s|is|n)?)|ábamos)' # I think that's right 

Se non includo 'hablábamos' è facile - sono tutti lo stesso prefisso, e posso ottenere:

'hablaba(s|is|n)?' 

... ma voglio una forma generale. È possibile?

+1

Stai provando a * generare * un'espressione regolare dai valori nel dizionario? Oppure stai cercando di scrivere un'espressione regolare per * convalidare * i valori nel dizionario. O qualcos'altro interamente? – Johnsyweb

+1

Voglio generarlo. Il mio tag è sbagliato? –

risposta

6

Sì, credo che questo sia possibile .

Per iniziare, ecco come risolverei il problema.

calcolare la radice trovando la stringa più lunga possibile che corrisponde l'inizio di tutti i valori sono diminuiti:

>>> root = '' 
>>> for c in hablar['yo']: 
...  if all(v.startswith(root + c) for v in hablar.itervalues()): 
...   root += c 
...  else: 
...  break 
... 
>>> root 
'habl' 

ciò che resta delle parole fa un list di terminazioni.

>>> endings = [v[len(root):] for v in hablar.itervalues()] 
>>> print endings 
['abas', 'aba', 'abais', 'aba', '\xc3\xa1bamos', 'aban', 'abas'] 

Si può quindi consiglia di eliminare i duplicati:

>>> unique_endings = set(endings) 
>>> print unique_endings 
set(['abas', 'abais', '\xc3\xa1bamos', 'aban', 'aba']) 

quindi unire queste terminazioni insieme con i tubi:

>>> conjoined_endings = '|'.join(unique_endings) 
>>> print conjoined_endings 
abas|abais|ábamos|aban|aba 

Formare l'espressione regolare è una cosa semplice che unisce la radice e la stringa conjoined_endings tra parentesi:

>>> final_regex = '{}({})'.format(root, conjoined_endings) 
>>> print final_regex 
habl(abas|abais|ábamos|aban|aba) 
+1

Grazie @Johnsyweb, sì che aiuta. Ma non posso votarti :("richiede 15 reputazione". Devo accettarti? –

+0

@MalenaTorres: sei il benvenuto. Spero che questo ti possa iniziare anche se i miei termini linguistici sono off. Sono curioso del perché tu vuoi comprimere le espressioni regolari così tanto, non hai a che fare con una grande quantità di dati e le espressioni più complesse si aggiungeranno solo ai tuoi tempi di convalida. – Johnsyweb

+1

Ho reso il mio esempio più semplice di quello che è, in realtà sarà come '{'yo': '\ w + aba'}', & c. Infine voglio confrontare i verbi irregolari con quelli normali per le loro regole, e avrò un altro dict come 'yo = {'imperfecto': '\ w + aba', 'presente': '\ w + o'}'. Più complicato per i verbi irregolari, adesso, sto solo iniziando con la mia idea di vedere cosa posso fare. –

3

penso che è necessario avere un approccio meno intelligente

>>> x={ 
... 'yo': 'hablaba', 
... 'tú': 'hablabas', 
... 'él': 'hablaba', 
... 'nosotros': 'hablábamos', 
... 'vosotros': 'hablabais', 
... 'ellos': 'hablaban', 
... 'vos': 'hablabas', 
... } 
>>> x 
{'t\xc3\xba': 'hablabas', 'yo': 'hablaba', 'vosotros': 'hablabais', '\xc3\xa9l': 'hablaba', 'nosotros': 'habl\xc3\xa1bamos', 'ellos': 'hablaban', 'vos': 'hablabas'} 
>>> x.values 
<built-in method values of dict object at 0x20e6490> 
>>> x.values() 
['hablabas', 'hablaba', 'hablabais', 'hablaba', 'habl\xc3\xa1bamos', 'hablaban', 'hablabas'] 
>>> "|".join(x.values()) 
'hablabas|hablaba|hablabais|hablaba|habl\xc3\xa1bamos|hablaban|hablabas' 

Se hai appena uniscono i valori di hash con un operatore alternanza allora dovrebbe fare quello che vuoi

+1

Grazie Vorsprung :) Ma ho molte parole e altre coniugazioni (quella che ho dato è una coniugazione imperfetta, ce ne sono altre 15) e non voglio usare troppo spazio. Ma sì, la tua idea funziona :) –

+1

Penso sempre che la memoria del computer è più economica del mio tempo prezioso :) – Vorsprung

+0

C'è sicuramente molto da dire per mantenerlo semplice! – Johnsyweb

Problemi correlati