dmulyalin / ttp

Template Text Parser
MIT License
351 stars 34 forks source link

Parse line with optional keyword #32

Closed resetsa closed 4 years ago

resetsa commented 4 years ago

HI!

Please tell me. I have intput text from device

.id=*c;export-route-targets=65001:48;65001:0;import-route-targets=65001:48;interfaces=lo-ext;vlan56;route-distinguisher=65001:48;routing-mark=VRF_EXT
.id=*10;comment=;export-route-targets=65001:80;import-route-targets=65001:80;65001:0;interfaces=lo-private;route-distinguisher=65001:80;routing-mark=VRF_PRIVATE

How i can write template which parse this string and return id comment export-route-targets import-route-targets interfaces route-distinguisher routing-mark

my best solution only this

<macro>
def split_kv(data):
    result = dict()
    for kv in data:
        if '=' in kv:
            k,v = kv.split('=')
            result[k] = v
    return result
</macro>
<!-- comment -->
{{<group name="vrfs">
{{ vrf | _line_ | split(';') | macro('split_kv') }}
</group>

I'm sorry, but I don’t know where else you can ask for help with this. Thank you for your work

dmulyalin commented 4 years ago

Hi,

Have a look at the docs for more parsing examples, go through previous issues on this repo, they also contain examples of templates.

You can ask questions on Slack channel as well - link in readme.

For your particular question - you have to enumerate all variations of line you trying to parse in your template:

data = """
.id=*c;export-route-targets=65001:48;65001:0;import-route-targets=65001:48;interfaces=lo-ext;vlan56;route-distinguisher=65001:48;routing-mark=VRF_EXT
.id=*10;comment=;export-route-targets=65001:80;import-route-targets=65001:80;65001:0;interfaces=lo-private;route-distinguisher=65001:80;routing-mark=VRF_PRIVATE
"""
template = """
<group method="table">
.id={{ id | exclude(";") }};export-route-targets={{ export-route-targets }};import-route-targets={{ import-route-targets }};interfaces={{ interfaces }};route-distinguisher={{ route-distinguisher }};routing-mark={{ routing-mark }}
.id={{ id }};comment{{ comment }};export-route-targets={{ export-route-targets }};import-route-targets={{ import-route-targets }};interfaces={{ interfaces }};route-distinguisher={{ route-distinguisher }};routing-mark={{ routing-mark }}
</group>
"""
parser = ttp(data, template)
parser.parse()
res = parser.result(structure="flat_list")
# pprint.pprint(res)
# prints:
# [{'export-route-targets': '65001:48;65001:0',
#   'id': '*c',
#   'import-route-targets': '65001:48',
#   'interfaces': 'lo-ext;vlan56',
#   'route-distinguisher': '65001:48',
#   'routing-mark': 'VRF_EXT'},
#   'comment': '=',
#   'export-route-targets': '65001:80',
#   'id': '*10',
#   'import-route-targets': '65001:80;65001:0',
#   'interfaces': 'lo-private',
#   'route-distinguisher': '65001:80',
#   'routing-mark': 'VRF_PRIVATE'}]
#   

Have a look in the docs for method="table" and for match variable exclude function description. exclude required because both template line match same text string, as a result need to filter one of them.

flat_list - also expalined in the docs in API reference section