Reputation: 103
When using Python 3 with Regex I am getting unexpected results. I want to do something like this
firstpass = re.findall('\s+((10|192|172).\d{1,3}.\d{1,3}.\d{1,3}/(\d+))', line)
Where it would look for spaces, then numbers starting with 10 or 192 or 172 and then any 3 octets after (IPv4 addresses).
I understand the grouping but I either get only one of the first three values. Or if I change the grouping around I get get 3 returns (but still only 1 of the initial search values) I've tried as many variations as I can read about. the [10|192|172] just doesn't work. inside () groupings of course.
I am looking for two return strings. The IP and the mask. It works fine until I try to enlarge my expression to have a more complex search.
the end goal is to look for ANY private IP space in one regex expression.
10.match.match.match
172.16-32.match.match
192.168.match.match
So the data may look like this and I want to pull 1 -3 but not the last line
B 10.50.13.0 /26 blah foo
O 192.169.5.0 /24 foo foo
B 172.18.0.0/16 etc etc
B 82.33.4.0/24 yak yak yak
Upvotes: 1
Views: 98
Reputation: 626689
You need to escape all dots (since you want to match them as literal chars), only use capturing groups around those patterns that you want re.findall
to return and use non-capturing groups around the patterns you do not need it to yield, and use word boundaries.
re.findall(r'\b((?:10|192|172)(?:\.\d{1,3}){3}\s*/(\d+))', s)
See the regex demo.
See the Python demo:
import re
rx = r"\b((?:10|192|172)(?:\.\d{1,3}){3}\s*/(\d+))"
ss = ["B 10.50.13.0 /26 blah foo", "O 192.169.5.0 /24 foo foo", "B 172.18.0.0/16 etc etc", "B 82.33.4.0/24 yak yak yak"]
for s in ss:
print(s)
m = re.findall(rx, s)
if m:
print(m)
else:
print("NO MATCH")
Output:
B 10.50.13.0 /26 blah foo
[('10.50.13.0 /26', '26')]
O 192.169.5.0 /24 foo foo
[('192.169.5.0 /24', '24')]
B 172.18.0.0/16 etc etc
[('172.18.0.0/16', '16')]
B 82.33.4.0/24 yak yak yak
NO MATCH
Upvotes: 1