2

I'm trying to use \w{2}\d/\d{1,2}(/\d{1,2})? in order to match the following two interfaces on a Cisco switch:

Gi1/0/1

Fa0/1

  1. When I use re.search(), it returns the desired output.

    import re
    port = "Gi1/0/1 Fa0/1"
    search = re.search(r'\w{2}\d/\d{1,2}(/\d{1,2})?', port)
    print search.group()
    

I get "Gi1/0/1" as the output.

  1. When I use re.findall()

    import re
    port = "Gi1/0/1 Fa0/1"
    search = re.findall(r'\w{2}\d/\d{1,2}(/\d{1,2})?', port)
    print search
    

I get "['/1', '']" which is undesired.

Why does't findall() return ['Gi1/0/1','Fa0/1']?

Is that because I used (/\d{1,2})?, and findall() is supposed to return this part? Why is that?

How do we get ['Gi1/0/1','Fa0/1'] using findall()?

Parry Wang
  • 33
  • 4

3 Answers3

1

From the findall docs

If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group.

In you regex you have a capturing group (/\d{1,2})?

You could make it a non capturing group instead (?:/\d{1,2})?

Your regex would look like:

\w{2}\d/\d{1,2}(?:/\d{1,2})?

import re
port = "Gi1/0/1 Fa0/1"
search = re.findall(r'\w{2}\d/\d{1,2}(?:/\d{1,2})?', port)
print search

Demo

The fourth bird
  • 96,715
  • 14
  • 35
  • 52
0

search.group() returns entire match found by the regex \w{2}\d/\d{1,2}(/\d{1,2})?. It doesn't consider capturing group. It is equivalent to search.group(0). While using search.group(1), it will return /1: the result of first capturing group.

On other hand, re.findall returns all result of matched groups. To get the expected result, your regex should be

(\w{2}\d/(?:\d{1,2}/)?\d{1,2})

Python Code

>>> re.findall(r'(\w{2}\d/(?:\d{1,2}/)?\d{1,2})', port)
['Gi1/0/1', 'Fa0/1']

Regex Breakdown

( #Start Capturing group
  \w{2}\d/  #Match two characters in [A-Za-z0-9_] followed by a digit and slash
  (?:\d{1,2}/)? #Followed by two digits which are optional
  \d{1,2} #Followed by two digits
) #End capturing group

P.S. From your question, I think you are matching only alphabets. In that case use, [A-Za-z] instead of \w

rock321987
  • 10,292
  • 1
  • 23
  • 36
0

If you want it the regex way; this will work:

search = re.findall(r'\w{2}\d/\d{1}(?:/\d{1})?', port)

You may do this too:

>>> "Gi1/0/1 Fa0/1".split(' ')
['Gi1/0/1', 'Fa0/1']
  • Thank you for the answer. The interface name will vary depends on the model of the Cisco switch, some models are Gigabitethernet, some are FastEthernet. I have another larger script to capture these interfaces on different switches. Here I just provided a sample code to understand the difference between search() and findall(). – Parry Wang Jun 24 '18 at 07:56
  • Oh okay. I understand. – Aditya Aggarwal Jun 25 '18 at 09:01