REMARQUE: le code python n'est pas correct! C'est juste un pseudo-code approximatif de ce à quoi ça pourrait ressembler.
expressions régulières sont bonnes à la recherche et l'extraction des données de texte dans un format fixe (par exemple une date de JJ/MM/AAAA).
Une paire lexer/analyseur est bonne à des données de traitement dans un cadre structuré, mais le format quelque peu variable. Lexers a divisé le texte en jetons. Ces jetons sont des unités d'information d'un type donné (nombre, chaîne, etc.). Les parseurs prennent cette série de jetons et font quelque chose en fonction de l'ordre des jetons.
En regardant les données, vous disposez d'une structure de base (sujet, verbe, objet) dans différentes combinaisons pour la relation (personne, « anniversaire », date):
Je 29/9/10 et gérer 24-9-2010 en tant que simple jeton utilisant une regex, le renvoyant comme type de date. Vous pourriez probablement faire la même chose pour les autres dates, avec une carte pour convertir Septembre et sep à 9.
Vous pouvez ensuite retourner le tout le reste sous forme de chaînes (séparés par des espaces).
Vous avez alors:
- Date '' string 'anniversaire'
- string 'anniversaire' '' Date
Date
- 'anniversaire' 'de' chaîne de chaîne
date
- ' : 'string string 'anniversaire'
string
- 'anniversaire' Date
NOTE:' birthda y « », ', « : » et « de » ici sont des mots clés, donc:
class Lexer:
DATE = 1
STRING = 2
COMMA = 3
COLON = 4
BIRTHDAY = 5
OF = 6
keywords = { 'birthday': BIRTHDAY, 'of': OF, ',': COMMA, ':', COLON }
def next_token():
if have_saved_token:
have_saved_token = False
return saved_type, saved_value
if date_re.match(): return DATE, date
str = read_word()
if str in keywords.keys(): return keywords[str], str
return STRING, str
def keep(type, value):
have_saved_token = True
saved_type = type
saved_value = value
Tous sauf 3 Utilisez la forme possessive de la personne ('s
si le dernier caractère est une consonne, s
si elle est une voyelle).Cela peut être difficile, comme « Alexis » pourrait être la forme plurielle de « Alexi », mais puisque vous restreignez où les formes plurielles peuvent être, il est facile de détecter:
def parseNameInPluralForm():
name = parseName()
if name.ends_with("'s"): name.remove_from_end("'s")
elif name.ends_with("s"): name.remove_from_end("s")
return name
Maintenant, le nom peut être soit first-name
ou first-name last-name
(oui, je sais que le Japon les remplace, mais du point de vue du traitement, le problème ci-dessus n'a pas besoin de différencier les noms et prénoms). Ce qui suit traitera ces deux formes:
def parseName():
type, firstName = Lexer.next_token()
if type != Lexer.STRING: raise ParseError()
type, lastName = Lexer.next_token()
if type == Lexer.STRING: # first-name last-name
return firstName + ' ' + lastName
else:
Lexer.keep(type, lastName)
return firstName
Enfin, vous pouvez traiter les formulaires 1-5 en utilisant quelque chose comme ceci:
def parseBirthday():
type, data = Lexer.next_token()
if type == Lexer.DATE: # 1, 3 & 4
date = data
type, data = Lexer.next_token()
if type == Lexer.COLON or type == Lexer.COMMA: # 1 & 4
person = parsePersonInPluralForm()
type, data = Lexer.next_token()
if type != Lexer.BIRTHDAY: raise ParseError()
elif type == Lexer.BIRTHDAY: # 3
type, data = Lexer.next_token()
if type != Lexer.OF: raise ParseError()
person = parsePerson()
elif type == Lexer.STRING: # 2 & 5
Lexer.keep(type, data)
person = parsePersonInPluralForm()
type, data = Lexer.next_token()
if type != Lexer.BIRTHDAY: raise ParseError()
type, data = Lexer.next_token()
if type == Lexer.COMMA: # 2
type, data = Lexer.next_token()
if type != Lexer.DATE: raise ParseError()
date = data
else:
raise ParseError()
return person, date