1

I need to negate part of the IP address and get only the last two octets for example:

IP_Add1 192.168.10.1 LAN 10

I only want the last two octets of the IP Add (10.1), so I need my output looks like this:

IP_Add1 10.1 LAN 10

I have already tried with the following code, but I get an empty list [] as a result. any help?

str_2 = '''IP_Add1 192.168.10.1 LAN 10
IP_Add1 192.168.10.1 LAN 20
IP_Add1 192.168.20.1 LAN 30
IP_Add1 192.168.30.1 LAN 40
'''

print(re.findall(r"\w+ [\d]{3}.[\d]{3}.[\d]{2}.[\d]{1}", str_2))
pault
  • 41,343
  • 15
  • 107
  • 149
user3682875
  • 49
  • 1
  • 1
  • 5
  • You're using `re.findall` where you should probably be using `re.sub` (you'd need a different pattern too). Here is a link: [How to input a regex in string.replace?](https://stackoverflow.com/questions/5658369/how-to-input-a-regex-in-string-replace) – pault Apr 15 '19 at 19:07
  • 1
    You might want to focus on solving a *single* IP address, and once you have that, add in handling a sequence of them. – Scott Hunter Apr 15 '19 at 19:08

1 Answers1

0

I have already tried with the following code, but I get an empty list []

On the contrary, when I run you code, I get the following:

import re
str_2 = '''IP_Add1 192.168.10.1 LAN 10
IP_Add1 192.168.10.1 LAN 20
IP_Add1 192.168.20.1 LAN 30
IP_Add1 192.168.30.1 LAN 40
'''

print(re.findall(r"\w+ [\d]{3}.[\d]{3}.[\d]{2}.[\d]{1}", str_2))
#['IP_Add1 192.168.10.1', 'IP_Add1 192.168.10.1', 'IP_Add1 192.168.20.1', 'IP_Add1 192.168.30.1']

This is because re.findall will:

Return a list of all non-overlapping matches in the string.

But based on your wording, what you actually want to do is better accomplished using re.sub:

res = re.sub(r"(?<=IP_Add\d )\d{3}\.\d{3}\.(?=\d{2}\.\d{1})", "", str_2)
print(res)
#IP_Add1 10.1 LAN 10
#IP_Add1 10.1 LAN 20
#IP_Add1 20.1 LAN 30
#IP_Add1 30.1 LAN 40

If you wanted your results in a list, you can call the splitlines() method:

print(res.splitlines())
#['IP_Add1 10.1 LAN 10',
# 'IP_Add1 10.1 LAN 20',
# 'IP_Add1 20.1 LAN 30',
# 'IP_Add1 30.1 LAN 40']

The regular expression pattern used in sub is the following:

  • (?<=IP_Add\d ): Look-behind for the literal string "IP_Add" followed by exactly one digit and one space
  • \d{3}\.\d{3}\.: Three digits followed by a literal period, followed by another 3 digits and a literal period.
  • (?=\d{2}\.\d{1}): Look-ahead for two digits, a period, and then one digit.
pault
  • 41,343
  • 15
  • 107
  • 149
  • thanks @pault, i think this what i wanted to achieve, but I am wondering why i don't get the same result with the following code print(re.findall(r"\w+ [^\d]{3}\.[^\d]{3}\.[\d]{2}.[\d]{1}", str_2)) – user3682875 Apr 15 '19 at 20:38
  • @user3682875 test our your patterns on https://regex101.com/ and you'll see what the meaning is. For example, here is a [link](https://regex101.com/r/35xtxf/1) to the pattern I supplied in this answer. – pault Apr 15 '19 at 20:39