import re
input='''R1# show ip interface brief
Interface IP-Address OK? Method Status Protocol
--------------------------------------------------------------------------------
GigabitEthernet0/0 10.1.1.1 YES manual up up
GigabitEthernet0/1 172.16.10.1 YES DHCP up down
GigabitEthernet0/2 unassigned YES unset administratively down down
GigabitEthernet0/3 192.168.20.1 YES manual down down
Loopback0 1.1.1.1 YES manual up up
Loopback10 unassigned YES manual up up
Tunnel1 100.1.1.1 YES manual up down
Vlan100 10.100.1.1 YES manual down down
Serial0/0/0 172.30.1.2 YES manual up up
Serial0/0/1 172.30.2.2 YES manual up down
Port-channel1 192.168.50.1 YES manual up up'''
pattern=r'(\S+)\s+\S+\s+\S+\s+\S+\s+up+\s+\S+'
test=re.findall(pattern,input)
print(test)
#['GigabitEthernet0/0', 'GigabitEthernet0/1', 'Loopback0', 'Loopback10', 'Tunnel1', 'Serial0/0/0', 'Serial0/0/1', 'Port-channel1']
---
import re
## swap local port with remote port & change system name
text= '''user@switch> show lldp neighbors
Local Interface Parent Interface Chassis Id Port info System Name
xe-3/0/4.0 ae31.0 b0:c6:9a:63:80:40 xe-0/0/0.0 host.jnpr.net
xe-3/0/5.0 ae31.0 b0:c6:9a:63:80:40 xe-0/0/1.0 host.jnpr.net
xe-3/0/6.0 ae31.0 b0:c6:9a:63:80:40 xe-0/0/2.0 host.jnpr.net
xe-3/0/7.0 ae31.0 b0:c6:9a:63:80:40 xe-0/0/3.0 host.jnpr.net
xe-3/0/0.0 ae31.0 b0:c6:9a:63:80:40 xe-0/1/0.0 host.jnpr.net
xe-3/0/1.0 ae31.0 b0:c6:9a:63:80:40 xe-0/1/1.0 host.jnpr.net
xe-3/0/2.0 ae31.0 b0:c6:9a:63:80:40 xe-0/1/2.0 host.jnpr.net'''
s_text=text.split('\n')
#print(s_text)
print(f'Local Interface Parent Interface Chassis Id Port info System Name')
for x,y in enumerate(s_text,1):
if x > 2 :
ss=y.split()
print(f'{ss[3]}\t{ss[1]}\t{ss[2]}\t{ss[0]}\tmohan.com')
#####
outputt
Local Interface Parent Interface Chassis Id Port info System Name
xe-0/0/0.0 ae31.0 b0:c6:9a:63:80:40 xe-3/0/4.0 mohan.com
xe-0/0/1.0 ae31.0 b0:c6:9a:63:80:40 xe-3/0/5.0 mohan.com
xe-0/0/2.0 ae31.0 b0:c6:9a:63:80:40 xe-3/0/6.0 mohan.com
xe-0/0/3.0 ae31.0 b0:c6:9a:63:80:40 xe-3/0/7.0 mohan.com
xe-0/1/0.0 ae31.0 b0:c6:9a:63:80:40 xe-3/0/0.0 mohan.com
xe-0/1/1.0 ae31.0 b0:c6:9a:63:80:40 xe-3/0/1.0 mohan.com
xe-0/1/2.0 ae31.0 b0:c6:9a:63:80:40 xe-3/0/2.0 mohan.com
----
with open('mohan.txt','w') as f:
f.write('hello world \npython world \nlearning')
with open('mohan.txt','a') as f:
f.write('\nappending line4')
with open('mohan.txt','r') as f:
x=f.read()
print(type(x)) #<class 'str'>
print(x)
#output
'''
hello world
python world
learning
appending line4'''
with open('mohan.txt','r') as f:
x=f.readlines()
print(type(x)) #<class 'list'>
print(x) #['hello world \n', 'python world \n', 'learning\n', 'appending line4']
---
import re
text = """python1 is a scripting language
python2 hadles data structures list,dict,etc
it has lots of python3 liberiers"""
print(text)
pattern=r'python\d'
print("######### regex match #########")
m=re.match(pattern,text)
print(m) #<re.Match object; span=(0, 7), match='python1'>
print(type(m)) #<class 're.Match'>
print ('match output:',m.group()) #match output: python1
print ('match span:',m.span()) #match span: (0, 7)
print ('match start:',m.start()) #match start: 0
print ('match end:',m.end()) #match end: 7
print("##############################")
print("######### regex search #########")
s=re.search(pattern,text)
print(s) #<re.Match object; span=(0, 7), match='python1'>
print(type(s)) #<class 're.Match'>
print ('match output:',s.group()) #match output: python1
print("##############################")
print("######### regex findall #########")
fa=re.findall(pattern,text)
print(fa) #['python1', 'python2', 'python3']
print(len(fa)) #3
print(type(fa)) #<class 'list'>
print ('match output:',fa[0]) #match output: python1
print ('match output:',fa[1]) #match output: python2
print ('match output:',fa[2]) #match output: python3
print("##############################")
print("######### regex finditer #########")
fi=re.finditer(pattern,text)
print(fi) #<callable_iterator object at 0x000001EDEAEB9030>
print(type(fi)) #<class 'callable_iterator'>
for x in fi:
print ('match output:',x)
print ('match output:',x.group())
'''
#output
match output: <re.Match object; span=(0, 7), match='python1'>
match output: python1
match output: <re.Match object; span=(32, 39), match='python2'>
match output: python2
match output: <re.Match object; span=(92, 99), match='python3'>
match output: python3
'''
print("##############################")
##Name capturing group
import re
text = "My IP is 192.168.100.11"
p = r'(?P<oct1>\d{1,3})\.(?P<oct2>\d{1,3})\.(?P<oct3>\d{1,3})\.(?P<oct4>\d{1,3})'
match = re.search(p, text)
print(match.group("oct1")) # 192
print(match.group("oct2")) # 168
print(match.group("oct3")) # 100
print(match.group("oct4")) # 11
## look ahead & look beyond examples
1. Positive Lookahead (?=...)
Pattern: \d+(?=USD)
Text: 100USD
Regex: \d+ (?=USD)
Matches "100" because it is followed by "USD".
2. Positive Lookbehind (?<=...)
Pattern: (?<=USD)\d+
Text: USD100
Regex: (?<=USD) \d+
Matches "100" because it is preceded by "USD".
3. Negative Lookahead (?!...)
Pattern: \d+(?!USD)
Text: 200EUR
Regex: \d+ (?!USD)
Matches "200" because after digits we don’t see "USD".
4. Negative Lookbehind (?<!...)
Pattern: (?<!USD)\d+
Text: EUR300
Regex: (?<!USD) \d+
Matches "300" because before digits we don’t see "USD".
Pattern: \d+(?=USD)
Text: 100USD
Regex: \d+ (?=USD)
Matches "100" because it is followed by "USD".
2. Positive Lookbehind (?<=...)
Pattern: (?<=USD)\d+
Text: USD100
Regex: (?<=USD) \d+
Matches "100" because it is preceded by "USD".
3. Negative Lookahead (?!...)
Pattern: \d+(?!USD)
Text: 200EUR
Regex: \d+ (?!USD)
Matches "200" because after digits we don’t see "USD".
4. Negative Lookbehind (?<!...)
Pattern: (?<!USD)\d+
Text: EUR300
Regex: (?<!USD) \d+
Matches "300" because before digits we don’t see "USD".
-----
import re
test= '''
this line has valid ip 192.168.100.11
this line has invalid 256.255.0.1
1.1.1.1
'''
pattern=r'\b((25[0-5]|2[0-4]\d|1\d\d|\d[1-9]?)\.){3}(25[0-5]|2[0-4]\d|1\d\d|\d[1-9]?)\b'
regex = re.compile(pattern)
print("Number of capturing groups:", regex.groups)
validate = re.findall(pattern,test)
print(validate[0])
## output will be
""""
Number of capturing groups: 3
('100.', '100', '11')
Group 1:Matches the whole repeated thing (BUT findall returns only the last repetition):
> '100.' #((25[0-5]|2[0-4]\d|1\d\d|\d[1-9]?)\.) > outer (())
Group 2:Matches the final occurrence of the 3 repeated octets
> 100 #(25[0-5]|2[0-4]\d|1\d\d|\d[1-9]?) > inner ()
Group 3:Matches the final octet: '11'
> 11 #(25[0-5]|2[0-4]\d|1\d\d|\d[1-9]?) > 2nd ()
"""
print(validate[0])
#('100.', '100', '11')
print(validate[1])
#('1.', '1', '1')
print(validate[2])
#IndexError: list index out of range
#due to only 2 matches in the above input test file
#Solution: use below pattern
#escape capturing groups >> ?:
pattern=r'\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|\d[1-9]?)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|\d[1-9]?)\b'
---
#Example-2
## re.multiline example
import re
text = """Hello World
Python is fun
Regex is powerful"""
pattern = r"^\w+"
matches = re.findall(pattern, text)
print(matches) #['Hello']
matches2 = re.findall(pattern, text, re.MULTILINE)
print(matches2) #['Hello', 'Python', 'Regex']
#Example-3
##pattern matching group ##
import re
text = "this has ip address 190.168.0.25"
match =r'\b(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[0-9]?\d)){3}\b'
compiled = re.compile(match)
print("Number of capturing groups:", compiled.groups)
test=re.findall(match,text)
for items in test:
print(items)
if test:
print("valid IP")
else:
print("invalid ip")
##output
Number of capturing groups: 3
('190', '.25', '25')
valid IP
explanation
Regex: (G1) (G2: (\. (G3) ){3})
Input: 190 . 168 . 0 . 25
Step 1: G1 = 190
Step 2: G2 = .168, G3 = 168
Step 3: G2 = .0, G3 = 0
Step 4: G2 = .25, G3 = 25 <-- last repetition stored
#Example-4
#same example with escape group (?:)
import re
text = "this has ip address 190.168.0.25"
match =r'\b(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[0-9]?\d)){3}\b'
compiled = re.compile(match)
print("Number of capturing groups:", compiled.groups)
test=re.findall(match,text)
for items in test:
print(items)
if test:
print("valid IP")
else:
print("invalid ip")
## output
Number of capturing groups: 0
190.168.0.25
valid IP
#Example-5
## multiple line as input
import re
text = """this has ip address 190.168.0.25 & 3.3.4.2
second line 1.1.1.1
and thirs line 33.33.33.33 """
match =r'\b(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[0-9]?\d)){3}\b'
compiled = re.compile(match)
print("Number of capturing groups:", compiled.groups)
test=re.findall(match,text)
for items in test:
print(items)
if test:
print("valid IP")
else:
print("invalid ip")
##output
Number of capturing groups: 0
190.168.0.25
3.3.4.2
1.1.1.1
33.33.33.33
valid IP
#Example-6
### corner case
if input is - 300.3.3.3.3
above regexp match - 3.3.3.3
if you want to exclude that condition use lookahead & look beyond
match = r'(?<!\d)(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}(?!\d)'
#Example-7
## findall vs finditer
import re
text = """Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 192.168.1.1 YES manual up up
GigabitEthernet0/1 unassigned YES unset administratively down down
GigabitEthernet0/2 10.0.0.1 YES manual down down
GigabitEthernet0/3 172.16.0.1 YES manual administratively down down
FastEthernet0/4 unassigned YES unset err-disabled down
"""
match=r'^(?P<iface>\S+)\s+\S+\s+\S+\s+\S+\s+administratively\s+down'
#compiled = re.compile(match)
#print("Number of capturing groups:", compiled.groups)
test=re.finditer(match,text,re.MULTILINE)
print(f'Finditer result >>> {test}')
test2=re.findall(match,text,re.MULTILINE)
print(f'Findall result >>> {test2}')
##output
Finditer result >>> <callable_iterator object at 0x7e77a17f5e70>
Findall result >>> ['GigabitEthernet0/1', 'GigabitEthernet0/3']

0 Comments