我正在尝试为某些文本编写解析器。我究竟做错了什么? 考虑以下pyparsing代码
from pyparsing import CaselessLiteral,StringEnd,Suppress,alphanums,alphas,alphas,
Word,ParseException,ParseResults,nums,Group,ZeroOrMore,ParseElement,restOfline,Combine,Optional,Literal,LineEnd
ParseElement.enablePackrat()
import lxml.etree
#define common syntax
delimiter=Supress("->")|Suppress(">")
line_ending=";"
cust_seperator="_"
cust_code=Word(alphanums)
description=Word(alphanums+"~#!@£$%^&*()'-+/{}[]=. ")
limit_state=CaselessLiteral("REACHED")|CaselessLiteral("NOT_REACHED")|CaselessLiteral("RETIRED")
#define grammar for user comment
StringStart=CaselessLiteral("COMMENT")
comment_text=Word(alphanums+"#!@£$%^&*()<>'/{}[]=. ")
usercomment_syntax=(StringStart+delimiter+comment_text+line_ending).setResultsNmae('user_comment')
#define grammar for upperlimit
StringStart=CaselessLiteral("CUSTOMER_LIMIT_REACHED")
cust_code_prefix=Word(alphanums,max=6)
customer_identifier=Combine(cust_code_prefix+Optional(cust_seperator)+cust_code+Optional(description))
customerupperlimit=(StringStart+delimiter+customer_identifier+delimiter+limit_state+line_ending).setResultsNmae('customer_upper_limit')
请考虑以下
评论 - &gt;欢迎来到银行;
这传递并且令牌是['评论','欢迎银行一',';']
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry mop]->NOT_REACHED;
这传递并且令牌是
['CUSTOMER_LIMIT_REACHED','1234_A0001 [Harry mop]','NOT_REACHED',';']
但是当&gt;是在“错误”的地方?
CUSTOMER_LIMIT_REACHED->1234_A0001 [Sally >12 top]->NOT_REACHED;
这对我来说似乎不适用于&gt;在描述中导致错误。所以重新定义这样的描述
description = Word(alphanums +“〜#!@£$%^&amp; *()' - + / {} [] =。&gt;”)
应该有效,但它会破坏注释语法。 我只想要分隔符 - &gt;被视为一个
考虑一下我不认为
delimiter=Suppress("->")| Suppress(">")
肯定我只需要
delimiter=Suppress("->")
谢谢,@保罗。我试过你的建议。
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") + ('-' + ~FollowedBy('>'))))
我不知道我输错了什么,但打破连字符证明有点棘手
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry-mop]->NOT_REACHED;
现在失败了,如果我是对的,我相信
(' - '+〜FollowedBy('&gt;') 期望在单词之后出现连字符( - ),因为它必须如此,所以
CUSTOMER_LIMIT_REACHED-&gt; 1234_A0001 [Harry-mop] - &gt; NOT_REACHED; 但失败了 CUSTOMER_LIMIT_REACHED-&gt; 1234_A0001 [Harry-mop] - &gt; NOT_REACHED; 通行证。
经过一些实验后我稍微调整了答案
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") + Optional('-' + ~FollowedBy('>'))))
感谢让我走上正确的道路
答案 0 :(得分:1)
是的,问题在于
description=Word(alphanums+"~#!@£$%^&*()'-+/{}[]=. ")
如果您添加&#39;&gt;&#39;对于description
中的这组允许字符,pyparsing将无法区分&#39; - &gt;&#39;这是描述与&#39; - &gt;&#39;的一部分。这是分隔符(因为&#39; - &#39;&#39;&gt;&#39;包含在允许的字符集中)。
你需要实施一个消极的前瞻,以便&#39; - &#39;或者&#39;&gt;&#39;单独将是可接受的描述内容。但是,在Word的令牌构建中,没有办法做到这一点。你需要突破&#39; - &#39; (作为&#39; - &gt;&#39;)中的主角作为一个单独的东西。
description = (OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") +
('-' + ~FollowedBy('>'))))
将整个事物包含在一个Combine中,以便pyparsing不会为此描述的单独位提供单独的字符串:
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") +
('-' + ~FollowedBy('>'))))
此时,delimiter = Suppress('->')
就足够了。