2013-08-20 31 views
1

我有一個簡單的句子 - 「tok0,084040,tok1,tok2,231108」 裏是時候(八點四十分40秒)和是日期(2008年11月23日)如何使用pyparsing將令牌放置在不同的位置?

繼在pyparsing文檔,我寫的規則來解析令牌:

 
    from pyparsing import * 
    d = Literal(',').suppress() 
    two_digits = Word(nums, exact=2) 
    tok0 = Word(nums) 
    time_token = two_digits("hour") + two_digits("min") + two_digits("sec") 
    tok1 = Word(alphas) 
    tok2 = oneOf('A B C') 
    date_token = two_digits("day") + two_digits("month") + two_digits("year") 
    grammar = (tok0 + d + time_token + d + tok1 + d + tok2 + d + date_token) 
我要的是有一個邏輯組在我 ParseResults包括 time_tokendate_token,這樣我可以使用 setParseActio, setResultsName爲組。考慮到他們不相鄰,就像
Group(time_token + date_token)
dreamGroup = Group(time_token + date_token)("datetime").setParseAction(myFn) 
parseResults = grammar.parseString("123,084040,ABC,A,231108") 
datetime = parseResults.datetime
P.S .: grammar.parseString的結果應該是ParseResults的一個實例。

+0

你的意思是'08:40:40'對嗎? –

+0

當然。我馬上解決它。 – Hangul

回答

2

您可以在解析操作的主體中添加結果名稱,並且它們將保留在解析的標記中。

def addDateTimeResults(tokens): 
    tokens['date'] = ('20'+tokens.year, tokens.month, tokens.day) 
    tokens['time'] = (tokens.hour, tokens.min, tokens.sec) 
    tokens['datetime'] = ParseResults([tokens.date, tokens.time]) 
    for name in ('date', 'time'): 
     tokens['datetime'][name] = tokens[name] 
grammar.setParseAction(addDateTimeResults) 

現在,在您的示例代碼,添加一個調用dump(),看看你會得到什麼:

parseResults = grammar.parseString("123,084040,ABC,A,231108") 
datetime = parseResults.datetime 
print datetime.dump() 

,你會得到:

[('2008', '11', '23'), ('08', '40', '40')] 
- date: ('2008', '11', '23') 
- time: ('08', '40', '40') 

而不是插入和返回的元組或者,您可以構造一個實際的Python日期時間對象,並返回該對象:

import datetime 
def addDateTimeResults(tokens): 
    dtfields = map(int, (tokens[fld] for fld in "year month day hour min sec".split())) 
    # adjust 2-digit year for 21st century 
    dtfields[0] += 2000 
    tokens['datetime'] = datetime.datetime(*dtfields) 

現在print parseResults.datetime給出:

2008-11-23 08:40:40 

這是一個Python日期時間對象的默認字符串表示。

0

更改語法級別的parseResults解決了問題。所以我稍微midified你回答,它像一個魅力。


def changeGrammarParseResults(s, loc, toks): 
    toks['datetime_8601'] = datetime.datetime(
     toks.pop('year'), toks.pop('month'), toks.pop('day'), 
     toks.pop('hour'), toks.pop('minute'), toks.pop('second'), 
     tzinfo=pytz.utc).isoformat()
+0

您應該將其移至您的問題。你應該避免「謝謝你」的答案。 – Jiri

+0

不錯,我忘了支持'pop()'的ParseResults。這是否將2000年添加到2位數年份?你是否將年,月,日等數字字符串轉換爲其他地方的字符串? (很容易通過在'two_digits'表達式中添加一個分析動作來完成) – PaulMcG

+0

是的,我省略了一些代碼(將字符串轉換爲整數,將2000年添加到年等),以專注於該問題。是的,我通過添加addParseAction到two_digits))謝謝pyparsing和你的幫助! – Hangul

相關問題