3

我想知道我在这里做错了什么。也许有人可以给我这个问题的提示。我想使用以字符串结尾的 pyparsing 来检测某些标记_Init

例如,我将以下行存储在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结尾处有 a 的行。但结果并不完整:

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

有人知道我在这里做错了什么吗?

4

1 回答 1

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
于 2013-04-30T04:32:35.647 回答