2010-11-10 15 views
6

Sto cercando di utilizzare il parser Earley in NLTK per analizzare frasi quali:Utilizzando interi/date come terminali in NLTK parser

Se la data è prima di 12/21/2010 allora di serie = 10

Per fare ciò, sto provando a scrivere un CFG ma il problema è che avrei bisogno di avere un formato generale di date e interi come terminali, invece dei valori specifici. Esistono modi per specificare il lato destro di una regola di produzione come un'espressione regolare, che consentirebbe questo tipo di elaborazione?

Qualcosa di simile:

S -> '[0-9]+' 

che gestire tutti gli interi.

+0

Il formato della data dipende dalle impostazioni internazionali. E soprattutto è ambiguo (si scontrano con un'espressione matematica 12 div 21 div 2010 che probabilmente non è quello che vuoi – VGE

+0

Hai ragione ma sarà facile da gestire in quanto l'input non conterrà mai espressioni matematiche come quello che hai menzionato. il formato della data verrà corretto, ad esempio, MM/GG/AAAA. Ho trovato un modo per gestire gli interi, ma sto ancora cercando una soluzione adeguata per le date. – FahimH

risposta

2

Per far funzionare questo, è necessario tokenize la data in modo che ogni cifra e barra sia un token separato.

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"]) 

Il risultato è:

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

Questo dà anche una certa flessibilità nella forma di permettere date e mesi di essere sola cifra.