[英]lexical analyse or series of regular expressions to parse unstructured text into structured form
我正在嘗試編寫一些功能,如Google日歷快速添加功能。 您知道可以在其中輸入以下內容的人:1)2010年9月24日,約翰斯誕辰2)約翰的生日,24/9/10 3)2010年9月24日,約翰·多伊誕辰4)24-9-2010:約翰做生日5)約翰做生日2010年9月24日
它可以弄清楚我們希望日期為24/9/2010的事件將其余材料作為事件文本。
我想做的是python。
我正在考慮一個設計,在其中編寫與上面列出的所有情況匹配的正則表達式並提取日期。 但是我可以找到一種更聰明的方法來解決這個問題。 因為我顯然沒有接受過詞法分析或多種類型的解析器樣式的培訓。 我正在尋找一種解決此問題的好方法。
注意:此處的python代碼不正確! 這只是它看起來的粗略偽代碼。
正則表達式擅長從固定格式的文本中查找和提取數據(例如DD / MM / YYYY日期)。
詞法分析器/解析器對擅長處理結構化但有些可變的格式的數據。 Lexers將文本拆分為標記。 這些令牌是給定類型(數字,字符串等)的信息單元。 解析器采用這一系列令牌,並根據令牌的順序執行某些操作。
查看數據,您會得到一個基本的(主體,動詞,賓語)結構,該結構以不同的組合關系(人,“生日”,日期):
我將使用正則表達式將29/9/10和24-9-2010作為單個令牌處理,並將其作為日期類型返回。 您可能還可以對其他日期執行相同的操作,並使用地圖將9月和9月轉換為9。
然后,您可以將其他所有內容都返回為字符串(由空格分隔)。
然后,您將擁有:
注意:“ birthday”,“,”,“:”和“ of”是關鍵字,因此:
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
所有除3使用人的所有格形式( 's
,如果最后一個字符是一個輔音, s
如果它是一個元音)。 這可能很棘手,因為“ Alexis”可能是“ Alexi”的復數形式,但是由於您限制了復數形式的位置,因此很容易檢測到:
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
現在,名字可以是first-name
或first-name last-name
(是的,我知道日本會交換first-name last-name
,但是從處理的角度來看,上述問題不需要區分名字和姓氏)。 下面將處理這兩種形式:
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
最后,您可以使用以下方法處理表格1-5:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.