我有不同格式的日期前缀和其他前缀。我需要创建一个可以跳过这个前缀并获得所需数据的语法。但是,当我使用SkipTo
和Or(^)
运算符时,我无法获得所需的结果。
from pyparsing import *
import pprint
def print_cal(v):
print v
f=open("test","r")
NAND_TIME= Group(SkipTo(Literal("NAND TIMES"),include=True) + Word(nums)+Literal(":").suppress()+Word(nums)).setParseAction(lambda t: print_cal('NAND TIME'))
TEST_TIME= Group(SkipTo(Literal("TEST TIMES"),include=True) + Word(nums)+Literal(":").suppress()+Word(nums)).setParseAction(lambda t: print_cal('TEST TIME'))
testing =NAND_TIME ^ TEST_TIME
watch=OneOrMore(testing)
watch.parseString(f.read())
文件内容:
01 may 2015 15:15:100 NAND TIMES 1: 88008888 01 april 2015 15:15:100 NAND TIMES 2: 77777777 1154544 15:15:100 TEST TIMES 1: 78544545 8787878 aug 2015 15:15:100 TEST TIMES 2: 78787878
输出:
TEST TIME TEST TIME
期望的输出:
NAND TIME NAND TIME TEST TIME TEST TIME
任何人都可以帮我理解这个吗?
答案 0 :(得分:4)
使用SkipTo作为解析器的第一个元素有点粗体,可能表明searchString或scanString是比parseString更好的选择(searchString和scanString允许你只定义你感兴趣的输入部分) ,其余的将被自动跳过 - 但你必须注意你的“你想要的”的定义是明确的,并且不会意外地拾取不需要的位。)这是你使用searchString实现的解析器:
NAND_TIME= (Literal("NAND TIMES") + Word(nums)+Literal(":").suppress()+Word(nums)).setParseAction(lambda t: print_cal('NAND TIME'))
TEST_TIME= (Literal("TEST TIMES") + Word(nums)+Literal(":").suppress()+Word(nums)).setParseAction(lambda t: print_cal('TEST TIME'))
testing =NAND_TIME | TEST_TIME
testdata = f.read()
for match in testing.searchString(testdata):
print match.asList()
'|'在这种情况下使用非常好,因为从NAND开始或从TEST开始之间不会产生混淆。
您可能还会考虑一次解析此文件:
for line in f:
if not line: continue
print line
print testing.searchString(line).asList()
print