使用停止令牌解析字符串

时间:2018-02-06 16:05:29

标签: python pyparsing

假设解析器接受字母abc以及三者的任意组合。我想调用具有满足以下条件的子字符串的函数:

  1. 子字符串以a
  2. 开头
  3. 子字符串在遇到abc
  4. 之前终止
  5. 子字符串不以abc
  6. 开头

    例如,我们有以下字符串:

    bb cc ab bc cb bc abc bca bbb acc cbc ccc abc

    我想用字符串ab bc cbacc cbc ccc

    调用该函数

    我尝试按如下方式实现:

    import pyparsing as pp
    
    x = pp.OneOrMore(pp.Word("abc") + ~pp.Literal("abc"))
    x.addCondition(lambda tokens: tokens[0] != "abc")
    x.addCondition(lambda tokens: tokens[0][0] == "a")
    x.addParseAction(lambda tokens: print("x)", tokens))  # Print action for debugging
    
    y = pp.Word("abc")
    y.addParseAction(lambda tokens: print("y)", tokens))
    
    text = pp.OneOrMore(x ^ y)
    text.parseString("bb cc ab bc cb bc abc bca bbb acc cbc ccc abc")
    

    但由于某种原因,这个过早地停止 1个单词,这是输出:

    y) ['bb']
    y) ['cc']
    x) ['ab', 'bc', 'bc']
    y) ['cb']
    y) ['abc']
    y) ['bca']
    y) ['bbb']
    x) ['acc', 'cbc']
    y) ['ccc']
    y) ['abc']
    

    另外,如果abc停止令牌是一个不同字符串的列表,它们都可以作为停止标记,那该怎么解析呢?

    类似于:

    stopStrings = ["abc", "bca"]
    x = pp.OneOrMore(pp.Word("abc") + ~pp.OneOf(stopStrings))
    ...
    

    希望这清楚地表明并感谢你的帮助!

2 个答案:

答案 0 :(得分:2)

这可能接近你想要的。我不明白你的第三个条件。

  • token的定义坚持认为stop_tokens之一,并且它是由Word组成的token来自setParseAction { A,b,C}。
  • 当识别出parser时,token会发送一个请求,表明如果第一个字符是'a'则会显示。
  • 整个stop_token只有stop_token个,后跟任意数量的stop_token。在此上下文中,每个import pyparsing as pp def report_a(s): try: if s[0][0]=='a': print (s[0], "begins with 'a'") except: pass def report(s): print ('stop token encountered') stop_tokens = pp.Or([pp.Literal('abc'), pp.Literal('bca')]) token = pp.NotAny(stop_tokens) + pp.Word('abc').setParseAction(lambda s: report_a(s)) parser = pp.ZeroOrMore(token) + pp.ZeroOrMore(stop_tokens).setParseAction(lambda s: report(s)).suppress() text = 'bb cc ab bc cb bc abc bca bbb acc cbc ccc abc' print (parser.parseString(text)) 都被抑制。同时,如果识别出ab begins with 'a' stop token encountered ['bb', 'cc', 'ab', 'bc', 'cb', 'bc'] ,则会发出一条消息,表明已经看到了一条消息。

代码:

System.Reflection.Metadata

结果:

GetOrAddUserString()

答案 1 :(得分:0)

我想我已经明白了。 This SO question/answer was very helpful.比尔贝尔的回答帮助我获得了超过1个终止字符串。

stop_strings = ["abc", "acb"]
stop_tokens = pp.Or([pp.Literal(sub) for sub in stop_strings])

x = pp.OneOrMore(~stop_tokens + pp.Word("abc")) + pp.Optional(stop_tokens.suppress())
x.addCondition(lambda tokens: tokens[0][0] == "a")
x.addParseAction(lambda tokens: print("x)", tokens))  # Print action for debugging

y = pp.Word("abc")
y.addParseAction(lambda tokens: print("y)", tokens))

text = pp.OneOrMore(x ^ y)
text.parseString("bb cc acb ab cb abc bca bbb acc cbc ccc")

输出:

y) ['bb']
y) ['cc']
y) ['acb']
x) ['ab', 'cb']
y) ['bca']
y) ['bbb']
x) ['acc', 'cbc', 'ccc']