Validating IPv4 addresses with regexp
You've already got a working answer but just in case you are curious what was wrong with your original approach, the answer is that you need parentheses around your alternation otherwise the (\.|$)
is only required if the number is less than 200.
'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
^ ^
Using a RegEx to match IP addresses
You have to modify your regex in the following way
pat = re.compile("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
that's because .
is a wildcard that stands for "every character"
Regex for matching IPv4 addresses
The following Regex matches IPs from 0.0.0.0
to 255.255.255.255
, not preceded or followed by a period or a digit:
(?<![\.\d])(?:[0-9]\.|1\d?\d?\.|2[0-5]?[0-5]?\.){3}(?:[0-9]|1\d?\d?|2[0-5]?[0-5]?)(?![\.\d])
Demo: https://regex101.com/r/UUCywc/3
Edit: to avoid matching IPs with a negative number as the first digit (eg. -127.2.1.2
), and to allow IPs like 001.001.001.001
, then use:
(?<![-\.\d])(?:0{0,2}?[0-9]\.|1\d?\d?\.|2[0-5]?[0-5]?\.){3}(?:0{0,2}?[0-9]|1\d?\d?|2[0-5]?[0-5]?)(?![\.\d])
Demo: https://regex101.com/r/UUCywc/6
Full Python implementation:
import re
str1 = 'Hello my name is Ben and my IP address is 127.1.1.1'
str2 = 'Hello my name is Folks and my IP address is 1.2.3.4.5'
str3 = 'Hello all, ip addresses: 1.2.3.4.5, 127.1.2.1, 127.2.1.2'
def find_ip(test_str):
regex = re.compile(r"(?<![-\.\d])(?:0{0,2}?[0-9]\.|1\d?\d?\.|2[0-5]?[0-5]?\.){3}(?:0{0,2}?[0-9]|1\d?\d?|2[0-5]?[0-5]?)(?![\.\d])")
return regex.findall(test_str)
print(find_ip(str1)) #['127.1.1.1']
print(find_ip(str2)) #[]
print(find_ip(str3)) #['127.1.2.1', '127.2.1.2']
How to match an ip address in mysql?
You're going to need to use REGEXP
to match the IP address dotted quad pattern.
SELECT *
FROM yourtable
WHERE
thecolumn REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$'
Technically, this will match values that are not valid IP addresses, like 999.999.999.999
, but that may not be important. What is important, is fixing your data such that IP addresses are stored in their own column separate from whatever other data you have in here. It is almost always a bad idea to mix data types in one column.
mysql> SELECT '9876543210' REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$';
+---------------------------------------------------------------------------+
| '9876543210' REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$' |
+---------------------------------------------------------------------------+
| 0 |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT '987.654.321.0' REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$';
+------------------------------------------------------------------------------+
| '987.654.321.0' REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$' |
+------------------------------------------------------------------------------+
| 1 |
+------------------------------------------------------------------------------+
Another method is to attempt to convert the IP address to a long integer via MySQL's INET_ATON()
function. An invalid address will return NULL
.
This method is likely to be more efficient than the regular expression.
You may embed it in a WHERE
condition like: WHERE INET_ATON(thecolumn) IS NOT NULL
SELECT INET_ATON('127.0.0.1');
+------------------------+
| INET_ATON('127.0.0.1') |
+------------------------+
| 2130706433 |
+------------------------+
SELECT INET_ATON('notes');
+--------------------+
| INET_ATON('notes') |
+--------------------+
| NULL |
+--------------------+
SELECT INET_ATON('56.99.9999.44');
+----------------------------+
| INET_ATON('56.99.9999.44') |
+----------------------------+
| NULL |
+----------------------------+
Regex for find All ip address except IP address starts with 172
.
in a regex is character that matches everything. To use it in this context, you must escape it.
Also to limit it to just ip addresses that start with 172, simply hardcode it into your regex like so:
^172\.\d{1,3}\.\d{1,3}.\d{1,3}$
Debuggex Demo
You could then use this to filter out any matches already made.
Alternatively, if you're not starting with a list of ip addresses, you could use a negative look-ahead to grab them all straight away.
^(?!172)\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$
Debuggex Demo
Be a little careful in that this may match more than ip addresses - for example 400.660.226.602
would be captured - even though real IP4 addresses do not contain numbers higher than 255
. Perhaps this won't affect your use case - but it's something to remember.
As per the comments below, if you are searching for IP addresses anywhere in the document, rather than on their own line, use \b
instead of ^
and $
\b(?!172)\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}\b
Debuggex Demo
This would match log formats for example, which contain an ip address within the message rather than on it's own line.
[10:01:22] Connection from
10.14.242.211
established.
Regex to match an IP address
Don't use a regex when you don't need to :)
$valid = filter_var($string, FILTER_VALIDATE_IP);
Though if you really do want a regex...
$valid = preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/', $string);
The regex however will only validate the format, the max for any octet is the max for an unsigned byte, or 255
.
This is why IPv6 is necessary - an IPv4 address is only 32bits long and the internet is popular :)
How can I find an IP address in a long string with REGEX?
import re
secv = "90.123.1.100 akmfiawnmgisa gisamgisamgsagr[sao l321r1m r2p4 2342po4k2m4 22.33.4.aer 1.2.3.5344 99.99.99.100 asoifinagf sadgsangidsng sg 13.18.19.100 1.2.3.4"
b = re.findall(r"(?:\s|\A)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s|\Z)",secv)
b = list(filter(lambda x: all([int(y) <= 255 for y in x.split('.')]), b))
print(b)
To make it more interesting I added IP addresses at the beginning and end of your string. I am assuming that the ip address needs to be separated by white space on both sides if not at the beginning or end of the string. So I added to the REGEX at the beginning a non-capturing group (?:\s|\A) that will match either a white space character or the beginning of the string. I have also added to the end of the REGEX a lookahead assertion (?=\s|\Z) that will match a single white space character or the end of the line without consuming any characters. The above prints out:
['90.123.1.100', '99.99.99.100', '13.18.19.100', '1.2.3.4']
javascript regular expression to check for IP addresses
The regex you've got already has several problems:
Firstly, it contains dots. In regex, a dot means "match any character", where you need to match just an actual dot. For this, you need to escape it, so put a back-slash in front of the dots.
Secondly, but you're matching any three digits in each section. This means you'll match any number between 0 and 999, which obviously contains a lot of invalid IP address numbers.
This can be solved by making the number matching more complex; there are other answers on this site which explain how to do that, but frankly it's not worth the effort -- in my opinion, you'd be much better off splitting the string by the dots, and then just validating the four blocks as numeric integer ranges -- ie:
if(block >= 0 && block <= 255) {....}
Hope that helps.
Related Topics
Secure and Flexible Cross-Domain Sessions
Downloading a Folder Through with Ftp Using PHP
Targeting Specific Email with the Email Id in Woocommerce
How to? Form Post to Multiple Locations
How to Fetch All the Row of the Result in PHP MySQL
MySQL PHP - Select Where Id = Array()
I Have a Base64 Encoded Png, How to Write the Image to a File in PHP
Get Date for Monday and Friday for the Current Week (Php)
How to Send Soap Xml via Curl and PHP
Codeigniter - File Upload Required Validation
How to Match Accented Characters with PHP Preg
PHP - Most Lightweight Psr-0 Compliant Autoloader
Detect In-App Browser (Webview) with PHP/Javascript
Using If(!Empty) with Multiple Variables Not in an Array
Prevent Direct Access to a PHP Page
How to Log All API Calls Using Guzzle 6