2010-11-10 8 views
6

Próbuję użyć parsera Earley w NLTK do analizowania zdań takich jak:Korzystanie liczby całkowite/daty jako terminale w NLTK parsera

Jeśli data jest przed 21.12.2010 następnie seryjny = 10

Aby to zrobić, próbuję napisać CFG, ale problemem jest to, że potrzebowałbym mieć ogólny format dat i liczb całkowitych jako terminali, zamiast konkretnych wartości. Czy istnieją jakieś sposoby na określenie prawej strony reguły produkcji jako wyrażenia regularnego, które umożliwiłoby tego rodzaju przetwarzanie?

Coś jak:

S -> '[0-9]+' 

który będzie obsługiwać wszystkie liczby całkowite.

+0

Twój format daty zależy od ustawień regionalnych. I przede wszystkim jest niejednoznaczny (zderzają się z matematycznym wyrazem 12 div 21 div 2010, który prawdopodobnie nie jest tym, który chcesz – VGE

+0

Masz rację, ale będzie to łatwe w obsłudze, ponieważ dane wejściowe nigdy nie będą zawierać żadnych wyrażeń matematycznych, takich jak to, o czym wspomniałeś. format daty zostanie naprawiony, powiedzmy, MM/DD/RRRR .. Znalazłem sposób obsługi liczb całkowitych, ale wciąż szukam odpowiedniego rozwiązania dla dat. – FahimH

Odpowiedz

2

Aby to zadziałało, musisz tokenizować datę, aby każda cyfra i ukośnik były oddzielnym tokenem.

from nltk.parse.earleychart import EarleyChartParser 
import nltk 

grammar = nltk.parse_cfg(""" 
DATE -> MONTH SEP DAY SEP YEAR 
SEP -> "/" 
MONTH -> DIGIT | DIGIT DIGIT 
DAY -> DIGIT | DIGIT DIGIT 
YEAR -> DIGIT DIGIT DIGIT DIGIT 
DIGIT -> '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' 
""") 

parser = EarleyChartParser(grammar) 
print parser.parse(["1", "/", "1", "0", "/", "1", "9", "8", "7"]) 

Wyjście jest:

(DATE 
    (MONTH (DIGIT 1)) 
    (SEP /) 
    (DAY (DIGIT 1) (DIGIT 0)) 
    (SEP /) 
    (YEAR (DIGIT 1) (DIGIT 9) (DIGIT 8) (DIGIT 7))) 

ta daje również pewną elastyczność w postaci pozwalając Daty i miesiąc będzie jednocyfrowe.

Powiązane problemy