Skip to content

Instantly share code, notes, and snippets.

@jlinoff
Last active January 12, 2018 20:27
Show Gist options
  • Save jlinoff/f6369fb69e1bf43f14d8ec6b7c4c650c to your computer and use it in GitHub Desktop.
Save jlinoff/f6369fb69e1bf43f14d8ec6b7c4c650c to your computer and use it in GitHub Desktop.
Find and replace IPv4 addresses in python.
#!/usr/bin/env python
'''
Find all IPv4 addresses on a line and replace the interesting
ones.
Interesting IP addresses are those that are not in the exclude
list.
'''
# License: MIT Open Source
# Copyright (c) 2018 by Joe Linoff
from __future__ import print_function
import re
import sys
OCTET = r'(?:25[0-5]|2[0-4]\d|[01]?\d\d?)'
PATTERN = re.compile(r'\b(?:{octet}\.){{3}}{octet}\b'.format(octet=OCTET))
#PATTERN = re.compile(r'''
#\b
#(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}
#(?:25[0-5]|2[0-4]\d|[01]?\d\d?)
#\b
#''', re.VERBOSE)
def find(pattern, line):
'''
Return a generator will find all valid IPv4 addresses on the line.
'''
return (mip for mip in pattern.findall(line))
def fix(pattern, line, replace, xips):
'''
Fix a line by replacing all matching IP addresses on the
line with specified replacement.
'''
for mip in find(pattern, line):
if not xips or mip not in xips:
line = re.sub(r'(?<![-\.\w\d])' + mip + r'(?![-\.\w\d])', replace, line)
return line
def test():
'''
test
'''
verbose = False
for opt in sys.argv:
if opt in ['-v', '--verbose']:
verbose = True
def comp(pattern, replace, line, match, xips=None):
'''
Compare the results of the fix operation and report.
'''
newline = fix(pattern, line, replace, xips)
passed = newline == match
if passed:
if verbose:
print('\033[32;1mPASSED:\033[0m "{}" {}'.format(replace, xips))
else:
print('\033[32;1mPASSED:\033[0m "{:<64}" "{}" {}'.format(line, replace, xips))
else:
print('\033[31;1mFAILED:\033[0m "{}" {}'.format(replace, xips))
if verbose or not passed:
print('\tinput "{}"'.format(line))
print('\toutput "{}"'.format(newline))
print('\texpected "{}"'.format(match))
print('\tpattern "{}"'.format(pattern.pattern))
rep = 'a.b.c.d'
comp(PATTERN, rep,
'1.2.3',
'1.2.3')
comp(PATTERN, rep,
'1.2.3.4',
'a.b.c.d')
comp(PATTERN, rep,
'1.2.3.4 ',
'a.b.c.d ')
comp(PATTERN, rep,
' 1.2.3.4 ',
' a.b.c.d ')
comp(PATTERN, rep,
' 1.2.3.4',
' a.b.c.d')
comp(PATTERN, rep,
'1.2.3.4 5.6.7.8 9.0.1.2',
'a.b.c.d a.b.c.d a.b.c.d')
comp(PATTERN, rep,
' 1.2.3.4 5.6.7.8 ',
' a.b.c.d a.b.c.d ')
comp(PATTERN, rep,
'x1.2.3.4',
'x1.2.3.4')
comp(PATTERN, rep,
'1.2.3.4x',
'1.2.3.4x')
comp(PATTERN, rep,
'1.2.3.4.5',
'1.2.3.4.5')
comp(PATTERN, rep,
'1.2.3.4.5',
'1.2.3.4.5')
comp(PATTERN, rep,
'1 1.2 1.2.3 1.2.3.4 1.2.3.4.5',
'1 1.2 1.2.3 a.b.c.d 1.2.3.4.5')
comp(PATTERN, rep,
' 100.200.300.400 ',
' 100.200.300.400 ')
comp(PATTERN, rep,
' http://1.2.3.4:800/foo/bar ',
' http://a.b.c.d:800/foo/bar ')
comp(PATTERN, rep,
' http://1.2.3.4:800/foo/bar http://127.0.0.1:8080 ',
' http://a.b.c.d:800/foo/bar http://127.0.0.1:8080 ',
xips='127.0.0.1')
if __name__ == '__main__':
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment