Padfoot123
Padfoot123

Reputation: 1117

Replace ip partially with x in python

I have several ip addresses like

162.1.10.15
160.15.20.222
145.155.222.1

I am trying to replace the ip's like below.

162.x.xx.xx
160.xx.xx.xxx
145.xxx.xxx.x

How to achieve this in python.

Upvotes: 1

Views: 92

Answers (7)

EVGENY OGRYZKOV
EVGENY OGRYZKOV

Reputation: 1

Oneliner FYI:

import re

ips = ['162.1.10.15', '160.15.20.222', '145.155.222.1']
pattern = r'\d{1,3}'
replacement_sign = 'x'

res = [re.sub(pattern, replacement_sign, ip[::-1], 3)[::-1] for ip in ips]

print(res)

Upvotes: 0

Boseong Choi
Boseong Choi

Reputation: 2596

Solution 1

Other answers are good, and this single regex works, too:

import re


strings = [
    '162.1.10.15',
    '160.15.20.222',
    '145.155.222.1',
]

for string in strings:
    print(re.sub(r'(?:(?<=\.)|(?<=\.\d)|(?<=\.\d\d))\d', 'x', string))

output:

162.x.xx.xx
160.xx.xx.xxx
145.xxx.xxx.x

Explanation

  • (?<=\.) means following by single dot.
  • (?<=\.\d) means follwing by single dot and single digit.
  • (?<=\.\d\d) means following by single dot and double digit.
  • \d means a digit.
  • So, all digits that following by single dot and none/single/double digits are replaced with 'x'
  • (?<=\.\d{0,2}) or similar patterns are not allowed since look-behind ((?<=...)) should has fixed-width.

Solution 2

Without re module and regex,

for string in strings:
    first, *rest = string.split('.')
    print('.'.join([first, *map(lambda x: 'x' * len(x), rest)]))

above code has same result.

Upvotes: 1

HelpfulHelper
HelpfulHelper

Reputation: 294

Pass an array of IPs to this function:

def replace_ips(ip_list):
    r_list=[]
    for i in ip_list:
        first,*other=i.split(".",3)
        r_item=[]
        r_item.append(first)
        for i2 in other:
            r_item.append("x"*len(i2))
        r_list.append(".".join(r_item))
    return r_list

In case of your example:

print(replace_ips(["162.1.10.15","160.15.20.222","145.155.222.1"]))#==> expected output: ["162.x.xx.xx","160.xx.xx.xxx","145.xxx.xxx.x"]

Upvotes: 0

Farhan Mushtaq
Farhan Mushtaq

Reputation: 11

This is not the optimize solution but it works for me .

import re
Ip_string = "160.15.20.222"
Ip_string = Ip_string.split('.')
Ip_String_x =""
flag = False
for num in Ip_string:
  if flag:
    num = re.sub('\d','x',num)
    Ip_String_x = Ip_String_x + '.'+ num
  else:
    flag = True
    Ip_String_x = num

Upvotes: 1

Sivadithiyan
Sivadithiyan

Reputation: 83

There are multiple ways to go about this. Regex is the most versatile and fancy way to write string manipulation codes. But you can also do it by same old for-loops with split and join functions.

ip = "162.1.10.15"

#Splitting the IPv4 address using '.' as the delimiter
ip = ip.split(".")

#Converting the substrings to x's except 1st string
for i,val in enumerate(ip[1:]):
    cnt = 0
    for x in val:
        cnt += 1
    ip[i+1] = "x" * cnt

#Combining the substrings back to ip
ip = ".".join(ip)
print(ip)

I highly recommend checking Regex but this is also a valid way to go about this task.

Hope you find this useful!

Upvotes: 0

Abhijit Sarkar
Abhijit Sarkar

Reputation: 24518

Here’s a slightly simpler solution

import re

txt = "192.1.2.3"

x = txt.split(".", 1) # ['192', '1.2.3']
y = x[0] + "." + re.sub(r"\d", "x", x[1])

print(y) # 192.x.x.x

Upvotes: 3

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521178

We can use re.sub with a callback function here:

def repl(m):
    return m.group(1) + '.' + re.sub(r'.', 'x', m.group(2)) + '.' + re.sub(r'.', 'x', m.group(3)) + '.' + re.sub(r'.', 'x', m.group(4))

inp = "160.15.20.222"
output = re.sub(r'\b(\d+)\.(\d+)\.(\d+)\.(\d+)\b', repl, inp)
print(output)  # 160.xx.xx.xxx

In the callback, the idea is to use re.sub to surgically replace each digit by x. This keeps the same width of each original number.

Upvotes: 3

Related Questions