I need to split space-delimited TCL lists on double braces... for instance...
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}}}"""
This should parse into...
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}}}"""]
I have tried...
import re
splitter = re.compile('}}\s+{{')
splitter.split(OUTPUT)
However, that trims the braces in the center...
['{{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}}}']
I can't figure out how to only split on the spaces between }} {{
. I know I can cheat and insert missing braces manually, but I would rather find a simple way to parse this out efficiently.
Is there a way to parse OUTPUT
with re.split
(or some other python parsing framework) for an arbitrary number of space-delimited rows containing {{content here}}
?
Pyparsing has improved since that comp.lang.python discussion, and I think even Cameron Laird would not complain about a solution using pyparsing's nestedExpr
method:
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
Prints:
[[['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"}}}']
If you are going to have to resplit the data to get the individual items from the nested braces, then the original nested list output from nestedExpr
might be of better help (note that even if a quoted string is in the list, the quoted item is kept as its own item). But if you really, really want that string containing the nested braces, then use the form with originalTextFor
shown in nestedBraces2
.
You could modify your regex to use positive lookahead/behind assertions, which don't consume any of the string:
re.compile('(?<=}})\s+(?={{)')
You can use a regular expression to extract, instead of split off, the list item values…
re.findall(r'({{.*?}})(?:\Z|\s+)', OUTPUT)
For example:
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}}}']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With