在Python中解析TCL列表

时间:2012-02-24 22:47:33

标签: python regex parsing tcl

我需要在双括号上拆分以空格分隔的TCL列表...例如......

OUTPUT = """{{172.25.50.10:01:01-Ethernet 172.25.50.10:01:02-Ethernet {Traffic Item 1}}} {{172.25.50.10:01:02-Ethernet 172.25.50.10:01:01-Ethernet {Traffic Item 1}}}"""

这应解析为......

OUTPUT = ["""{{172.25.50.10:01:01-Ethernet 172.25.50.10:01:02-Ethernet {Traffic Item 1}}}""", 
    """{{172.25.50.10:01:02-Ethernet 172.25.50.10:01:01-Ethernet {Traffic Item 1}}}"""]

我试过......

import re
splitter = re.compile('}}\s+{{')
splitter.split(OUTPUT)

但是,它修剪了中心的大括号......

['{{172.25.50.10:01:01-Ethernet 172.25.50.10:01:02-Ethernet {Traffic Item 1}',
'172.25.50.10:01:02-Ethernet 172.25.50.10:01:01-Ethernet {Traffic Item 1}}}']

我无法弄清楚如何只分割}} {{之间的空格。我知道我可以手动欺骗并插入缺少的大括号,但我宁愿找到一种简单的方法来有效地解析它。

有没有办法用OUTPUT(或其他一些python解析框架)解析包含re.split的任意数量的以空格分隔的行的{{content here}}

3 个答案:

答案 0 :(得分:4)

自comp.lang.python讨论以来,Pyparsing已有所改进,我认为即使Cameron Laird也不会抱怨使用pyparsing的nestedExpr方法的解决方案:

OUTPUT = """{{172.25.50.10:01:01-Ethernet 172.25.50.10:01:02-Ethernet {Traffic Item 1}}} {{172.25.50.10:01:02-Ethernet 172.25.50.10:01:01-Ethernet {Traffic "Item 1"}}}"""

from pyparsing import nestedExpr, originalTextFor

nestedBraces1 = nestedExpr('{', '}')
for nb in nestedBraces1.searchString(OUTPUT):
    print nb

nestedBraces2 = originalTextFor(nestedExpr('{', '}'))
for nb in nestedBraces2.searchString(OUTPUT):
    print nb

打印:

[[['172.25.50.10:01:01-Ethernet', '172.25.50.10:01:02-Ethernet', ['Traffic', 'Item', '1']]]]
[[['172.25.50.10:01:02-Ethernet', '172.25.50.10:01:01-Ethernet', ['Traffic', '"Item 1"']]]]
['{{172.25.50.10:01:01-Ethernet 172.25.50.10:01:02-Ethernet {Traffic Item 1}}}']
['{{172.25.50.10:01:02-Ethernet 172.25.50.10:01:01-Ethernet {Traffic "Item 1"}}}']

如果您不得不重新分割数据以从嵌套大括号中获取单个项目,那么nestedExpr的原始嵌套列表输出可能会有更好的帮助(请注意,即使引用的字符串在在列表中,引用的项目保留为自己的项目)。但是,如果您真的想要包含嵌套大括号的字符串,请使用originalTextFor中显示的nestedBraces2表单。

答案 1 :(得分:3)

您可以修改正则表达式以使用正向前瞻/后面断言,这些断言不会消耗任何字符串:

re.compile('(?<=}})\s+(?={{)')

答案 2 :(得分:1)

您可以使用正则表达式来提取而不是拆分列表项值......

re.findall(r'({{.*?}})(?:\Z|\s+)', OUTPUT)

例如:

In [30]: regex = re.compile(r'({{.*?}})(?:\Z|\s+)')

In [31]: regex.findall(OUTPUT)
Out[31]: 
['{{172.25.50.10:01:01-Ethernet 172.25.50.10:01:02-Ethernet {Traffic Item 1}}}',
 '{{172.25.50.10:01:02-Ethernet 172.25.50.10:01:01-Ethernet {Traffic Item 1}}}']