Regex - IPV4 | SoloLearn: Learn to code for FREE!

+1

Regex - IPV4

#CODE: import re def ipv4_address(address): n = "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])" pattern = n + "(\.)" + n + "(\.)" + n + "(\.)" + n + "$" return True if re.match(pattern, address) else False #Question: Why does it return True for address = '127.0.0.1\n' ?

1/26/2018 10:15:52 PM

David Handl

11 Answers

New Answer

+3

Sorry, but I cannot found a workaround: as I previously wrote the regex, it expect for anything else a new line char, but expect a char... but if you modify again by appending a question mark to the char class to make it optional, so the final new line char in address is even accepted, due to the final '$'. The only thing I can suggest now, is to test for presence of new lines char in another time... What I would do in this case, would be to trim new lines char (and spaces too) of the address string by: filtered_address = address.trim('\n ') # " \n \nwhatever else\n" will return "whatever else" And then return False if address != filtered_address, else do the real ipv4 regular expression test, without '[^\n']', but maybe also with '^' at start ;)

+3

@David Handl: Read closely my answers, all your questions are already answered ^^ Obviously, you can also just test for "\n" at end of the string to declare it ivalid and return False, rather than trim both sides, but if the tested string contains more that one "\n" at end, you will fail if you test only the last char, where my solution continue to work (return False if trimed string != original string) ;)

+3

I've just got another solution, practicing regular expressions on another subject... ... you can workaround with your question code version by using negative lookaround operator: pattern = n + "(\.)" + n + "(\.)" + n + "(\.)" + n + "(?!\n)$" So, '127.0.0.1\n' will return False, '127.0.0.1' True, and '127.0.0.1 ' False... as your (last) short version still do, obviously, but I think this information could be helpful ;) code playground: https://code.sololearn.com/c8yEZzx4artd/#py source of my discovery (basic regex snippet): https://www.regextester.com/15 deeper explanations about regex lookaround: https://www.regular-expressions.info/lookaround.html summary of regex lookaround: http://www.rexegg.com/regex-lookarounds.html

+2

New line character ('\n') is considered as end of line in regular expressions, so your pattern match the '\n' with the '$' checking for end of line as well as end of string ^^ If you want to get False for string ended with '\n', you should change your pattern by: pattern = n + "(\.)" + n + "(\.)" + n + "(\.)" + n + "[^\n]$" '[^abc]' define a class of characters to NOT ('^') accept ;)

+1

Unless you have to use regexes, you can just use a try/except structure with the ipaddress module. Try creating an IPV4Address object; if it isn't a valid address, it will throw an exception (I forget which one off the top of my head), which can be caught and handled. If you don't want to try that, you can modify this code of mine: https://code.sololearn.com/cRRD2bOZkiSX/?ref=app to your needs, and use that (no credit needed, it's quite simple). If you have to use regexes... try not to use regexes. There's usually a better solution, but regexes kinda just fit them all. In your case, you could use: addr = "".join(address.split("\n")) and use that variable. That should remove all the newlines in the address, which will make your check work. Pretty sure, haven't tested it out yet, though.

+1

Well thanks but I wanted it to work with regex and also it is a function to check whether the input is a correct IP or not. Therefore removing the newline characters will now return True even though the input was invalid. I will try something like an additional condition: If there is "\n" in the end of the string return False. I noticed that if "\n" is standing before the IP the regex does declare it as False. I would want to know why it doesn't work for both cases.... Also could I use endswith() function? I will try it :) Anyway you guys are a great help!

+1

For some reason I didn't see that part, thank you, I will try it!

+1

#Code: import re def ipv4_address(address): if address.strip() != address: return False n = "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" pattern = n + "(\.)" + n + "(\.)" + n + "(\.)" + n + "$" return True if re.match(pattern, address) else False #Comments: So now it works for a newline in the string and any valid address. I really appreciate your help guys! Thanks!

0

Thanks it helped! But now "0.0.0.0" returns False.

0

Short version: import re def ipv4_address(address): REGEX = re.compile(r'((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){4}$') return bool(re.match(REGEX, address + '.'))

0

# you doesn't provide argument to strip() method, and it's not the valid name: if address.trim('\n') != address: return False # obviously, you could even use rtrim('\n') in your specific case...