注意:這裏的python代碼是不正確的!這只是一個粗略的僞代碼,它看起來如何。
正則表達式擅長以固定格式(例如DD/MM/YYYY日期)從文本中查找和提取數據。
詞法分析器/解析器對擅長處理結構化但有點可變的格式的數據。 Lexers將文本分割爲令牌。這些令牌是給定類型(數字,字符串等)的信息單位。解析器使用這一系列令牌並根據令牌的順序做一些事情。
看一下數據,你有不同的組合基本(主語,動詞,賓語)結構的關係(人,「生日」,日期):
我會處理29/9/10和24-9-2010作爲使用正則表達式的單個令牌,將其作爲日期類型返回。你也許可以做的其他日期相同,與地圖轉換九月九至9
然後,您可以返回至上爲字符串(由空格隔開)。
然後,您有:
- 日期 '' '的' 串串
- 日期字符串 '生日'
- 字符串 '生日' '' 日期
- 日期 '生日'「 : '串串 '生日'
- 串串 '生日' 日期
注:' birthda Y「」,',‘:’和‘的’在這裏是關鍵字,因此:
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
如果是一個元音)。這可能會非常棘手,因爲「亞歷克西斯」可能是「阿列克謝」的複數形式,但因爲你是制約地方複數形式就可以了,很容易發現:
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
(是的,我知道日本將它們交換,但從處理的角度來看,上述問題不需要區分名字和姓氏)。下面將處理這兩種形式:
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