注: ここの python コードは正しくありません! これは、どのように見えるかの大まかな擬似コードです。
正規表現は、固定形式 (例: DD/MM/YYYY 日付) のテキストからデータを見つけて抽出するのに適しています。
レクサー/パーサーのペアは、構造化されたデータを処理するのに適していますが、多少可変の形式です。レクサーはテキストをトークンに分割します。これらのトークンは、特定のタイプ (数値、文字列など) の情報の単位です。パーサーはこの一連のトークンを受け取り、トークンの順序に応じて何かを行います。
データを見ると、関係 (人、「誕生日」、日付) のさまざまな組み合わせで基本的な (主語、動詞、目的語) 構造があります。
正規表現を使用して 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
さて、name は or のいずれかですfirst-name
(first-name last-name
はい、日本ではこれらが入れ替わっていることは知っていますが、処理の観点からは、上記の問題で名字と姓を区別する必要はありません)。以下は、これら 2 つの形式を処理します。
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