dmulyalin / ttp

Template Text Parser
MIT License
351 stars 34 forks source link

Help with indentation in templates #22

Closed aninchat closed 4 years ago

aninchat commented 4 years ago

Hi,

I have the following data I want to parse through, to simply extract the IP address of the interface.

In [68]: print(data)

interface Loopback0
 description Fabric Node Router ID
 ip address 192.2.101.70 255.255.255.255
 ip pim sparse-mode
 ip router isis 
 clns mtu 1400
end

With the assumption that my template will be indented in python code, I have added numerous whitespaces in the template and want to regex match on it to ignore the white spaces. The template I have is:

In [75]: print(show_run_parser_template)

   {{ ignore("\s+") }}ip address {{ ip_address }} 255.255.255.255

This is unable to parse through the data and I always get an empty list back. Any idea what I am doing wrong here?

dmulyalin commented 4 years ago

Probably you now invoking ttp parser object properly, this works for me using Python 3.7.7:

import pprint
from ttp import ttp

data = """
interface Loopback0
 description Fabric Node Router ID
 ip address 192.2.101.70 255.255.255.255
 ip pim sparse-mode
 ip router isis 
 clns mtu 1400
end
interface Loopback0
 description Fabric Node Router ID
 ip address 192.2.101.71 255.255.255.255
 ip pim sparse-mode
 ip router isis 
 clns mtu 1400
end
    """
template = """{{ ignore("\s+") }}ip address {{ ip_address }} 255.255.255.255"""
parser = ttp(data, template)
parser.parse()
res = parser.result()
pprint.pprint(res)

# prints:
# [[[{'ip_address': '192.2.101.70'}, {'ip_address': '192.2.101.71'}]]]
aninchat commented 4 years ago

I had tried the above method earlier and it works. However, lets say I create the template inside a python function, where it will automatically be indented, like so:

def parse(data):
    template = """
    {{ ignore("\s+") }}ip address {{ ip_address }} 255.255.255.255 <== indented whitespaces
    """
    parser = ttp(data=data, template=template)
    parser.parse()
    print(parser.result())

This is adding extra whitespaces due to the indentation and it breaks the template parsing. For one line templates, I can declare them inline and escape this problem. But for bigger templates, it is challenges and makes readability of the template difficult.

dmulyalin commented 4 years ago

Have a look at tests on how to define templates within functions using triple quotes: https://github.com/dmulyalin/ttp/blob/8e670842884c833fb6eace2b263931b2ab03ef26/test/pytest/test_anonymous_group.py#L28

aninchat commented 4 years ago

Thank you, this works perfectly.