如何使用pyparsing将令牌放置在不同的位置?
问题描述:
我有一个简单的句子 - “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_token和
date_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的一个实例。
答
您可以在解析操作的主体中添加结果名称,并且它们将保留在解析的标记中。
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日期时间对象的默认字符串表示。
答
更改语法级别的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()
你的意思是'08:40:40'对吗? –
当然。我马上解决它。 – Hangul