Search code examples
pythonregexcisconetmiko

AttributeError: 'NoneType' object has no attribute 'group' ,


I am trying to fetch the cisco version by Netmiko.

import re
from netmiko import ConnectHandler

iosv_l3 = {
    'device_type': 'cisco_ios',
    'ip': 'my ip',
    'username': 'username',
    'password': 'password',
    'secret': 'enable password'
}

net_connect = ConnectHandler(**iosv_l3)
net_connect.enable()
output = net_connect.send_command('show version | include flash')
print(output)
x = re.search(r'["]flash:/(.*)["]',output).group(1)
print(x)
net_connect.disconnect()

The Netmiko can SSH to Cisco equipment successfully. I can see the output from print(output):

System image file is "flash:c2900-universalk9-mz.SPA.156-3.M6.bin"

However, the code results in an error:

x = re.search(r'["]flash:/(.*)["]',output).group(1)
AttributeError: 'NoneType' object has no attribute 'group'

I created a test file to test regex:

import re
txt = "System image file is \"flash:/c2900-universalk9-mz.SPA.156-3.M6.bin\""
txt = re.search(r'["]flash:/(.*)["]',txt).group(1)
print(txt)

The test print "c2900-universalk9-mz.SPA.156-3.M6.bin" correctly.


Solution

  • The method re.match(..) returns Match object (which has .group(x) methods and etc) or None in case if the match was not found. In your case the error means that was returned None ;)

    Ok, it means that regex pattern doesn't work for the data tested. I've debugged your both cases and I've been noticed that in the first script you apply the pattern to is "flash:c2900- but in the second example you are testing the regex against file is \"flash:/c2900 where between flash: and c2900 we have an extra / which doesn't exist in the first example.

    Ok, so there are 2 ways to fix it - if you want to work it with and without / using the same regex, it will be this way

    import re
    
    output = 'System image file is "flash:c2900-universalk9-mz.SPA.156-3.M6.bin"'
    print(re.search(r'"flash:/?(.*)"', output).group(1))
    
    output = 'System image file is "flash:/c2900-universalk9-mz.SPA.156-3.M6.bin"'
    print(re.search(r'"flash:/?(.*)"', output).group(1))
    
    

    using optional regex matching (?).

    If you want to work only with / or without you can use these examples.

    import re
    
    output = 'System image file is "flash:c2900-universalk9-mz.SPA.156-3.M6.bin"'
    print(re.search(r'"flash:(.*)"', output).group(1))
    
    output = 'System image file is "flash:/c2900-universalk9-mz.SPA.156-3.M6.bin"'
    print(re.search(r'"flash:/(.*)"', output).group(1))