Python 如何使用pyparsing对放置在不同位置的令牌进行分组?

Python 如何使用pyparsing对放置在不同位置的令牌进行分组?,python,pyparsing,Python,Pyparsing,我有一个简单的句子——“tok0084040,tok1,tok2231108”,其中084040是时间(08:40:40),而231108是日期(23.11.2008) 在pyparsing文档之后,我编写了解析令牌的规则: 从pyparsing导入* d=文字(',')。抑制() 两位数=字(nums,精确=2) tok0=字(nums) 时间标记=两位数(“小时”)+两位数(“分钟”)+两位数(“秒”) tok1=字(字母) tok2=其中一个('A B C') 日期标记=两位数(“日”)

我有一个简单的句子——“tok0084040,tok1,tok2231108”,其中084040是时间(08:40:40),而231108是日期(23.11.2008)

在pyparsing文档之后,我编写了解析令牌的规则:

从pyparsing导入*
d=文字(',')。抑制()
两位数=字(nums,精确=2)
tok0=字(nums)
时间标记=两位数(“小时”)+两位数(“分钟”)+两位数(“秒”)
tok1=字(字母)
tok2=其中一个('A B C')
日期标记=两位数(“日”)+两位数(“月”)+两位数(“年”)
语法=(tok0+d+时间标记+d+tok1+d+tok2+d+日期标记)
我想要的是在我的ParseResults中有一个逻辑组,由time\u tokendate\u token组成,这样我就可以对组使用setParseActionsetResultsName。类似于
组(时间标记+日期标记)
的东西,考虑到它们不相邻。 Group(time_token + date_token)
dreamGroup=Group(时间标记+日期标记)(“日期时间”).setParseAction(myFn)
parseResults=grammar.parseString(“123084040,ABC,A,231108”)
datetime=parseResults.datetime

注意: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 datetime对象,而不是插入并返回元组:

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)
现在
打印解析结果。datetime
给出:

2008-11-23 08:40:40

这是Python datetime对象的默认字符串表示形式。

您可以在解析操作的主体中添加结果名称,它们将保留在解析的标记中

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 datetime对象,而不是插入并返回元组:

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)
现在
打印解析结果。datetime
给出:

2008-11-23 08:40:40

这是Python datetime对象的默认字符串表示形式。

在语法级别更改parseResults解决了此问题。所以我对你的回答略带迷幻,它就像一个符咒


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()

在语法级别更改parseResults解决了这个问题。所以我对你的回答略带迷幻,它就像一个符咒


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
对吧?当然。我马上修好。你是说
08:40:40
对吧?当然可以。我马上就解决。你应该把这个问题转移到你的问题上来。你应该避免回答“谢谢”。很好,我忘记了ParseResults支持
pop()
。这是否可以将2000年添加到2位数的年份?您是否正在将年、月、日等的数字字符串转换为其他地方的整数?(通过向
two_digits
表达式添加解析操作可以轻松完成)是的,我编写了一些代码(将字符串转换为整数,将2000添加到年份,等等)来关注这个问题。是的,我通过在两位数字上添加addParseAction实现了这一点。)谢谢你的PyParseing和你的帮助!你应该转移到你的问题上来。你应该避免回答“谢谢”。很好,我忘记了ParseResults支持
pop()
。这是否可以将2000年添加到2位数的年份?您是否正在将年、月、日等的数字字符串转换为其他地方的整数?(通过向
two_digits
表达式添加解析操作可以轻松完成)是的,我编写了一些代码(将字符串转换为整数,将2000添加到年份,等等)来关注这个问题。是的,我通过在两位数字上添加addParseAction实现了这一点。)谢谢你的PyParseing和你的帮助!