Last active
January 12, 2018 20:27
-
-
Save jlinoff/f6369fb69e1bf43f14d8ec6b7c4c650c to your computer and use it in GitHub Desktop.
Find and replace IPv4 addresses in python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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