Pyparsing:检测具有特定结尾的令牌

时间:2013-04-29 11:44:05

标签: python pyparsing

我想知道我在这里做错了什么。也许有人可以给我一个关于这个问题的暗示。 我想使用以字符串_Init终止的pyparsing来检测某些令牌。

例如,我在text

中存储了以下行
one
two_Init
threeInit
four_foo_Init
five_foo_bar_Init 

我想提取以下几行:

two_Init
four_foo_Init
five_foo_bar_Init 

目前,我已将问题简化为以下几行:

    import pyparsing as pp

    ident = pp.Word(pp.alphas, pp.alphanums + "_")
    ident_init = pp.Combine(ident + pp.Literal("_Init"))

    for detected, s, e in ident_init.scanString(text): 
        print detected

使用此代码没有结果。如果我删除"_"语句中的Word,那么我至少可以检测到其末尾有_Init的行。但结果并不完整:

['two_Init']
['foo_Init']
['bar_Init']

有人有任何想法,我在这里完全错了吗?

1 个答案:

答案 0 :(得分:2)

问题是,只要不是终止“_”中的“_”,您就会接受“_Init”。这里有两个pyparsing解决方案,一个是更“纯粹”的pyparsing,另一个只是用它来说它并使用嵌入式正则表达式。

samples = """\
one
two_Init
threeInit
four_foo_Init
six_seven_Init_eight_Init
five_foo_bar_Init"""


from pyparsing import Combine, OneOrMore, Word, alphas, alphanums, Literal, WordEnd, Regex

# implement explicit lookahead: allow '_' as part of your Combined OneOrMore, 
# as long as it is not followed by "Init" and the end of the word
option1 = Combine(OneOrMore(Word(alphas,alphanums) | 
                            '_' + ~(Literal("Init")+WordEnd())) 
                  + "_Init")

# sometimes regular expressions and their implicit lookahead/backtracking do 
# make things easier
option2 = Regex(r'\b[a-zA-Z_][a-zA-Z0-9_]*_Init\b')

for expr in (option1, option2):
    print '\n'.join(t[0] for t in expr.searchString(samples))
    print

两个选项都打印出来:

two_Init
four_foo_Init
six_seven_Init_eight_Init
five_foo_bar_Init