2013-02-18 12 views
7

Mam dyktować słowa (w rzeczywistości mam zagnieżdżone dyktaty koniugacji czasowników, ale to nie ma znaczenia) i chcę stworzyć wyrażeń regularnych, łącząc je.Jak mogę utworzyć wyrażenie regularne z listy słów?

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

... zrobić:

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

Gdybym nie obejmują 'hablábamos' to proste - wszystkie są takie same prefiks i mogę dostać:

'hablaba(s|is|n)?' 

... ale chcę ogólnej formy. Czy to jest możliwe?

+1

Czy próbujesz * wygenerować * wyrażenie regularne z wartości w słowniku? Czy próbujesz napisać wyrażenie regularne, aby * sprawdzić * wartości w słowniku. Lub coś zupełnie innego? – Johnsyweb

+1

Chcę go wygenerować. Czy mój tag jest nieprawidłowy? –

Odpowiedz

6

Tak, wierzę, że jest to możliwe .

Aby zacząć, w ten sposób zepsułbym problem.

Obliczyć pierwiastek poprzez znalezienie najdłuższy ciąg pasujący do rozpoczęcia wszystkich odrzuconych wartości:

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

Cokolwiek pozostało słów sprawia list zakończeń.

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

Następnie można chcieć pozbyć się duplikatów:

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

następnie dołączyć te końcówki wraz z rurami:

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

Formowanie wyrażenie regularne jest prostą sprawą łączenia korzeń oraz ciąg conjoined_endings w nawiasach:

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

Dziękuję @Johnsyweb, tak, to pomaga. Ale nie mogę cię głosować :("wymaga 15 reputacji" Czy mam cię zaakceptować? –

+0

@MalenaTorres: nie ma za co, na szczęście to ci się zacznie, nawet jeśli moje lingwistyczne terminy są wyłączone. chcesz tak mocno kompresować wyrażenia regularne, że nie masz do czynienia z dużą ilością danych, a bardziej złożone wyrażenia tylko zwiększą czas sprawdzania poprawności. – Johnsyweb

+1

Zrobiłem mój przykład prostszy niż jest, naprawdę będzie to jak '{'yo': '\ w + aba'}', & c. Na koniec chcę porównać nieregularne czasowniki do regularnych dla ich reguł, i będę miał inny dykt, taki jak 'yo = {'imperfecto': '\ w + aba', 'presente': '\ w + o'}'. Bardziej skomplikowane dla czasowników nieregularnych, teraz dopiero zaczynam z moim pomysłem, aby zobaczyć, co mogę zrobić. –

3

myślę, że trzeba mieć mniej mądry podejście

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

Jeśli tylko przyłączyć się do wartości hash z operatorem naprzemiennej to powinien robić to, co chcesz

+1

Dziękuję Vorsprung :) Ale mam dużo słów i innych koniugacji (ten, który dałem jest niedoskonałą koniugacją, jest ich około 15) i nie chcę używać zbyt wiele miejsca. Ale tak, twój pomysł działa :) –

+1

Zawsze uważam, że pamięć komputera jest tańsza niż mój cenny czas :) – Vorsprung

+0

Z pewnością jest wiele do powiedzenia na temat zachowania prostoty! – Johnsyweb

Powiązane problemy