使用pyparsing中的QuotedString

2024-06-09 08:12:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我在理解如何构建pyparsing解析器时遇到了概念上的困难。步骤是:1)通过组合ParserElement的子类来构建解析器,2)使用解析器解析字符串。在

以下示例效果良好:

from pyparsing import Word, Literal, alphas, alphanums, delimitedList, QuotedString

name = Word(alphas+"_", alphanums+"_")
field = name
fieldlist = delimitedList(field)
doc = Literal('<Begin>') + fieldlist + Literal('**End**')

dstring = '<Begin>abc,de34,f_o_o**End**'
print(doc.parseString(dstring))

生成预期的令牌序列:

^{pr2}$

但是(例如),QuotedString类没有将ParserElement作为参数,因此它不能用于构建解析器。我希望在上面的例子中使用它,比如:

name = Word(alphas+"_", alphanums+"_")
field = QuotedString(name)     ### Wrong: doesn't allow "name" as an argument
fieldlist = delimitedList(field)

要分析表单的文档:

dstring = '<Begin>"abc", "de34", "f_o_o"**End**'

但是既然不能这样使用,那么在构造一个引用字符串列表的解析器时包含QuotedString的正确语法是什么呢?在

=======编辑========

请看下面的答案。。。在


Tags: name解析器fieldpyparsingwordendbeginliteral
2条回答

我想您只是对如何使用QuotedString有点困惑。传递给QuotedString的参数是引号内的字符串,它是要用作引号的字符。通过这种方式,您可以定义用“*”作为引号,或“=”作为引号,或“<;”和“>;”开头和结尾引号字符的引号字符串。在您的示例中,只需对字段使用以下定义:

field = QuotedString('"')

另外,不要害怕使用python内置的help()方法来访问类、模块、方法等的docstring

编辑:

QuotedString('X')不解析"X",它解析X some characters inside matching characters X。在

以下是您的完整(工作)示例程序:

^{pr2}$

对我来说是:

['<Begin>', ['abc', 'de34', 'f_o_o'], '**End**']

如果在复制/粘贴此示例并运行它之后出现异常,发布完整的异常。在

还有一些例子:

starQuoteString = QuotedString('*')
eqQuoteString = QuotedString('=')
tildeQuoteString = QuotedString('~')
angleQuoteString = QuotedString('<', endQuoteChar='>')

fullSample = starQuoteString + eqQuoteString + tildeQuoteString + angleQuoteString

print fullSample.parseString("""
    *a string quoted with stars*
    =a very long quoted string, contained within equal signs=
    ~not a very long string at all~<another quoted string on the same line>
    """)

印刷品:

['a string quoted with stars', 'a very long quoted string, contained within equal signs', 'not a very long string at all', 'another quoted string on the same line']

你甚至不局限于单个字符。您可以使用QuotedString('**')来解析结束语**End**,但是这也接受**The End**,或者{},或者{}。在

QuotedString不能用于此任务。但是OR函数可以达到同样的效果——允许使用不同形式的引号,同时保留解析引号中包含的字符串的有效性的能力。以下代码可以做到这一点:

from pyparsing import Word, Literal, alphas, alphanums, delimitedList
from pyparsing import Group, QuotedString, ParseException, Suppress

name = Word(alphas+"_", alphanums+"_")
field = Suppress('"') + name + Suppress('"') ^ \    # double quote
        Suppress("'") + name + Suppress("'") ^ \    # single quote
        Suppress("<") + name + Suppress(">") ^ \    # html tag
        Suppress("{{")+ name + Suppress("}}")       # django template variable
fieldlist = Group(delimitedList(field))
doc = Literal('<Begin>') + fieldlist + Literal('**End**')

dstring = [
    '<Begin>"abc","de34","f_o_o"**End**',      # Good
    '<Begin><abc>,{{de34}},\'f_o_o\'**End**',  # Good
    '<Begin>"abc",\'de34","f_o_o\'**End**',    # Bad - mismatched quotes
    '<Begin>"abc","de34","f_o#o"**End**',      # Bad - invalid identifier
]

for ds in dstring:
    print(ds)
    try:
        print('  ', doc.parseString(ds))
    except ParseException as err:
        print(" "*(err.column-1) + "^")
        print(err)

这将产生所需的输出,接受两个良好的测试字符串并拒绝两个错误的测试字符串:

^{pr2}$

感谢保罗的所有帮助和制作如此酷的包。在

相关问题 更多 >