使用 pyparsing 的自定义分隔符
Custom Delimiter using pyparsing
我正在尝试为一些文本编写解析器。我究竟做错了什么?
考虑以下 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')
所以考虑以下
COMMENT->Welcome to bank one;
这通过了,令牌是 ['COMMENT','Welcome to bank one',';']
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry mop]->NOT_REACHED;
这通过了,令牌是
['CUSTOMER_LIMIT_REACHED','1234_A0001 [Harry mop]','NOT_REACHED',';']
但是当 > 在 "wrong" 位置时会发生什么?
CUSTOMER_LIMIT_REACHED->1234_A0001 [Sally >12 top]->NOT_REACHED;
这对我来说似乎不起作用,描述中出现 > 会导致错误。所以像这样重新定义描述
description=Word(alphanums+"~#!@£$%^&*()'-+/{}[]=.> ")
应该可以,但它会破坏注释语法。
我只想让定界符->被视为一个
想想我不觉得
delimiter=Suppress("->")| Suppress(">")
肯定是对的我只需要
delimiter=Suppress("->")
谢谢,@Paul。我试过你的建议。
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") + ('-' + ~FollowedBy('>'))))
我不知道我是不是打错了,但打破连字符有点棘手
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry-mop]->NOT_REACHED;
现在失败了,如果我是对的我相信
('-' + ~FollowedBy('>')
will expect a hyphen (-) to appear after the word, as in it MUST, so
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry-mop]->NOT_REACHED;
failed but
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry-mop]-->NOT_REACHED;
passes.
经过一些实验后,我将答案稍微调整为
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") + Optional('-' + ~FollowedBy('>'))))
谢谢你让我走上了正确的道路
是的,问题出在
description=Word(alphanums+"~#!@£$%^&*()'-+/{}[]=. ")
如果您将“>”添加到 description
中的这组允许的字符,pyparsing 将无法区分描述中的“->”与描述中的“->”是分隔符(因为“-”和“>”都包含在允许的字符集中)。
您将需要实施否定前瞻,以便“-”或“>”单独成为可接受的描述内容。然而,在 Word 的令牌构建中,没有办法做到这一点。您需要将“-”(作为“->”中的主导字符)单独分开。
description = (OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") +
('-' + ~FollowedBy('>'))))
将整个内容包装在一个 Combine 中,这样 pyparsing 就不会为这个描述的各个位提供单独的字符串:
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") +
('-' + ~FollowedBy('>'))))
此时,delimiter = Suppress('->')
应该足够了。
我正在尝试为一些文本编写解析器。我究竟做错了什么? 考虑以下 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')
所以考虑以下
COMMENT->Welcome to bank one;
这通过了,令牌是 ['COMMENT','Welcome to bank one',';']
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry mop]->NOT_REACHED;
这通过了,令牌是
['CUSTOMER_LIMIT_REACHED','1234_A0001 [Harry mop]','NOT_REACHED',';']
但是当 > 在 "wrong" 位置时会发生什么?
CUSTOMER_LIMIT_REACHED->1234_A0001 [Sally >12 top]->NOT_REACHED;
这对我来说似乎不起作用,描述中出现 > 会导致错误。所以像这样重新定义描述
description=Word(alphanums+"~#!@£$%^&*()'-+/{}[]=.> ")
应该可以,但它会破坏注释语法。 我只想让定界符->被视为一个
想想我不觉得
delimiter=Suppress("->")| Suppress(">")
肯定是对的我只需要
delimiter=Suppress("->")
谢谢,@Paul。我试过你的建议。
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") + ('-' + ~FollowedBy('>'))))
我不知道我是不是打错了,但打破连字符有点棘手
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry-mop]->NOT_REACHED;
现在失败了,如果我是对的我相信
('-' + ~FollowedBy('>') will expect a hyphen (-) to appear after the word, as in it MUST, so
CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry-mop]->NOT_REACHED; failed but CUSTOMER_LIMIT_REACHED->1234_A0001 [Harry-mop]-->NOT_REACHED; passes.
经过一些实验后,我将答案稍微调整为
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") + Optional('-' + ~FollowedBy('>'))))
谢谢你让我走上了正确的道路
是的,问题出在
description=Word(alphanums+"~#!@£$%^&*()'-+/{}[]=. ")
如果您将“>”添加到 description
中的这组允许的字符,pyparsing 将无法区分描述中的“->”与描述中的“->”是分隔符(因为“-”和“>”都包含在允许的字符集中)。
您将需要实施否定前瞻,以便“-”或“>”单独成为可接受的描述内容。然而,在 Word 的令牌构建中,没有办法做到这一点。您需要将“-”(作为“->”中的主导字符)单独分开。
description = (OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") +
('-' + ~FollowedBy('>'))))
将整个内容包装在一个 Combine 中,这样 pyparsing 就不会为这个描述的各个位提供单独的字符串:
description = Combine(OneOrMore(Word(alphanums+"~#!@£$%^&*()'+/{}[]=. >") +
('-' + ~FollowedBy('>'))))
此时,delimiter = Suppress('->')
应该足够了。