PyParsing:如何使用SkipTo和OR(^)运算符

时间:2014-08-08 19:41:49

标签: python python-2.7 python-3.x pyparsing

我有不同格式的日期前缀和其他前缀。我需要创建一个可以跳过这个前缀并获得所需数据的语法。但是,当我使用SkipToOr(^)运算符时,我无法获得所需的结果。

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

任何人都可以帮我理解这个吗?

1 个答案:

答案 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