dmulyalin / ttp

Template Text Parser
MIT License
350 stars 34 forks source link

Is there a way to handle multiple command options? #38

Closed chrispella closed 3 years ago

chrispella commented 3 years ago

I understand that we can group lines that have the same content from this example in the docs:

<input load="text">
interface Loopback0
 description Router-id-loopback
 ip address 192.168.0.113/24
!
interface Gi0/37
 description CPE_Acces
 switchport port-security
 switchport port-security maximum 5
 switchport port-security mac-address sticky
!
</input>

<group>
interface {{ interface }}
 ip address {{ ip }}/{{ mask }}
 description {{ description }}
 ip vrf {{ vrf }}
 {{ port_security_cfg | _line_ | contains("port-security") | joinmatches }}
! {{ _end_ }}
</group>

However, in the situation where something has different options... like below , where cir may not exist, it would be nice if there was something like in regexes where you can put a ? after a token so that ttp will try to match cir and assign cir_percent only if cir is present. Is there a way to do that without creating multiple lines beginning with percent-rate in the template?

percent-rate {{ pir_percent }} cir {{cir_percent }}
dmulyalin commented 3 years ago

Hi,

The best I can think of is this:

<input load="text">
percent-rate 98 cir 10
percent-rate 60 cir
percent-rate 50
</input>

<group name="foo">
percent-rate {{ pir_percent }} cir{{ cir_percent | strip | re("\S+") | re(".*") }}
</group>

it would give:

[
    [
        {
            "foo": [
                {
                    "cir_percent": "10",
                    "pir_percent": "98"
                },
                {
                    "cir_percent": "",
                    "pir_percent": "60"
                }
            ]
        }
    ]
]

As you can see it still probably not doing what you want.

The only way to match percent-rate 98 cir 10 and percent-rate 50 is to define several lines in the template.

<group name="foo">
percent-rate {{ pir_percent }} cir {{ cir_percent | default("") }}
percent-rate {{ pir_percent | _start_ }}
</group>

would produce:

[
    [
        {
            "foo": [
                {
                    "cir_percent": "10",
                    "pir_percent": "98"
                },
                {
                    "cir_percent": "",
                    "pir_percent": "50"
                }
            ]
        }
    ]
]

What is the problem with defining several lines in template for varying text data? Even though percent-rate 98 cir 10 and percent-rate 50 looks similar from human perspectives, IMHO for machine to parse it, the easiest way is to use two different regexes.

chrispella commented 3 years ago

No problem with defining multiple lines... I didn't realize you can use start that way.

dmulyalin commented 3 years ago

Yeah, _start_ helps to indicate that particular string should be threated as a start of the group during results collection, each group can have multiple _start_ lines defined depending on data you trying to parse.

Anything else I can help to clarify?