首页 > 解决方案 > 标记嵌套表达式但忽略带空格的引用字符串

问题描述

我正在寻找漂亮的打印以下字符串

r"file='//usr/env/0/test/0', name='test', msg=Test.Msg(type=String, bytes_=Bytes(value=b\" 0\x80\x00\x00y\x17\`\"))"

    file='//usr/env/0/test/0',
    name='test',
    msg=Test.Msg(
        type=String,
        bytes=Bytes(
            value=b\" 0\x80\x00\x00y\x17\`\""
        )
    )

首先,我尝试使用 pyparsing 对输入进行标记

from pyparsing import *
content = r"(file='//usr/env/0/test/0', name='test', msg=Test.Msg(type=String, bytes_=Bytes(value=b\" 0\x80\x00\x00y\x17\`\")))"
expr     = nestedExpr( '(', ')', ignoreExpr=None)
result = expr.parseString(content)
result.pprint()

这给了我一个嵌套列表,但是 Byte 数组在空格上被拆分

[["file='//usr/env/0/test/0',",
  "name='test',",
  'msg=Test.Msg',
  ['type=String,',
   'bytes_=Bytes',
   ['value=b\\"', '0\\x80\\x00\\x00y\\x17\\`\\"']]]]

任何人都知道我如何用逗号分隔以返回以下内容?

[["file='//usr/env/0/test/0',",
  "name='test',",
  'msg=Test.Msg',
  ['type=String,',
   'bytes_=Bytes',
   ['value=b\\" 0\\x80\\x00\\x00y\\x17\\`\\"']]]]

标签: pythonpyparsing

解决方案


为了得到想要的结果,我们需要为嵌套表达式的内容定义一个内容表达式。默认内容是任何带引号的字符串或空格分隔的单词。但我认为您的内容更像是一个逗号分隔的列表。

Pyparsing 在 pyparsing_common 中定义了一个 comma_separated_list 表达式,但是在这里它不会起作用,因为它不明白()嵌套表达式的 s 不应该是逗号分隔列表中项目的一部分。所以我们要写一个稍微修改的版本:

from pyparsing import *
content = r"""(file='//usr/env/0/test/0', name='test', msg=Test.Msg(type=String, bytes_=Bytes(value=b" 0\x80\x00\x00y\x17\`")))"""

# slightly modified comma_separated_list from pyparsing_common
commasepitem = (
        Combine(
            OneOrMore(
                ~Literal(",")
                + Word(printables, excludeChars="(),")
                + Optional(White(" ") + ~FollowedBy(oneOf(", ( )")))
            )
        )
    )
comma_separated_list = delimitedList(quotedString() | commasepitem)

expr     = nestedExpr( '(', ')', content=comma_separated_list)

result = expr.parseString(content)
result.pprint(width=60)

print(result.asList() == 
        [["file='//usr/env/0/test/0'",
          "name='test'",
          'msg=Test.Msg',
          ['type=String',
           'bytes_=Bytes',
           ['value=b" 0\\x80\\x00\\x00y\\x17\\`"']]]])

印刷:

[["file='//usr/env/0/test/0'",
  "name='test'",
  'msg=Test.Msg',
  ['type=String',
   'bytes_=Bytes',
   ['value=b" 0\\x80\\x00\\x00y\\x17\\`"']]]]
True

推荐阅读