views:

933

answers:

6

No not a competition, it is instead me trying to find why a certain regex works in one but not the other.

(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

That's my Regex and I'm trying to run it on

127.255.0.0

Using Pythons regex I get nothing, using PHP I match it, below are the two calls I am making (just incase it's something to do with that). Essentially I am trying to work out why it works in PHP but not Python.

re.findall(regex, string)
preg_match_all($regex, $string, $matches);


Solution found, it was due to the way that I was iterating through the results, this regex turned them into groups and then it didn't want to print them out in the same way etc etc. Thank you all for your help, it's really appreciated :)

+6  A: 

It works for me. You must be doing something wrong.

>>> re.match(r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)', '127.255.0.0').groups()
('127', '255', '0', '0')

Don't forget to escape the regex using raw strings: r'regex_here' as stated in the Regex Howto

nosklo
+1  A: 

That regular expression matches here, no idea what you are doing wrong:

>>> import re
>>> x = re.compile(r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|'
... r'2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]'
... r'[0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)')
>>> x.match("127.0.0.1")
<_sre.SRE_Match object at 0x5a8860>
>>> x.match("127.255.0.1")
<_sre.SRE_Match object at 0x5a8910>
>>> x.match("127.255.0.0")
<_sre.SRE_Match object at 0x5a8860>

Please note that preg_match translates to re.search in Python and not re.match. re.match is for useful for lexing because it's anchored.

Armin Ronacher
+1  A: 

PHP uses 3 different flavors of regex, while python uses only one. I don't code in python, so I make no expert claims on how it uses REGEX. O'Reilly Mastering Regular Expressions is a great book, as most of their works are.

WolfmanDragon
+4  A: 

I would suggest that using a regex for decimal range validation is not necessarily the correct answer for this problem. This is far more readable:

def valid_ip(s):
    m = re.match(r"(\d+)\.(\d+)\.(\d+)\.(\d+)$", s)
    if m is None:
        return False
    parts = [int(m.group(1+x)) for x in range(4)]
    if max(parts) > 255:
        return False
    return True
Greg Hewgill
+2  A: 

Without further details, I'd guess it's quote escaping of some kind. Both PHP and python's RegEX objects take strings as arguments. These strings will be escaped by the languge before being passed on to the RegEx engine.

I always using Python's "raw" string format when working with regular expressions. It ensure that "backslashes are not handled in any special way"

r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
Alan Storm
+3  A: 

Just because you can do it with regex, doesn't mean you should. It would be much better to write instructions like: split the string on the period, make sure each group is numeric and within a certain range of numbers.

If you want to use a regex, just verify that it kind of "looks like" an IP address, as with Greg's regex.

ruquay