Reputation: 1760
I'm having trouble understanding why I get the following results from a MySQL query of IP addresses. I'm storing IP addresses as INTEGERS.
mysql> SELECT ip AS ip FROM ipaddress;
+-----------+
| ip |
+-----------+
| 168456058 |
| 168456059 |
| 168456060 |
| 168456061 |
| 168456317 |
| 168456570 |
| 168489683 |
| 168489583 |
| 168489683 |
+-----------+
9 rows in set (0.00 sec)
Here is how the data looks when converting the INTEGERS to an IP address.
mysql> SELECT INET_NTOA(ip) AS ip FROM ipaddress;
+---------------+
| ip |
+---------------+
| 10.10.111.122 |
| 10.10.111.123 |
| 10.10.111.124 |
| 10.10.111.125 |
| 10.10.112.125 |
| 10.10.113.122 |
| 10.10.242.211 |
| 10.10.242.111 |
| 10.10.242.211 |
+---------------+
9 rows in set (0.00 sec)
When I search for a particular subnet, such as 111, I get the results I expect:
mysql> SELECT INET_NTOA(ip) AS ip FROM ipaddress WHERE INET_NTOA(ip) REGEXP '[[:<:]]111[[:>:]]';
+---------------+
| ip |
+---------------+
| 10.10.111.122 |
| 10.10.111.123 |
| 10.10.111.124 |
| 10.10.111.125 |
| 10.10.242.111 |
+---------------+
5 rows in set (0.00 sec)
If I use a decimal in the query, I get no results.
mysql> SELECT INET_NTOA(ip) AS ip FROM ipaddress WHERE INET_NTOA(ip) REGEXP '[[:<:]]\.111[[:>:]]';
Empty set (0.00 sec)
The decimal in the query works if I change the search query to .11. This time, though, I get all of the .111, and the .211.
mysql> SELECT INET_NTOA(ip) AS ip FROM ipaddress WHERE INET_NTOA(ip) REGEXP '[[:<:]]\.11[[:>:]]';
+---------------+
| ip |
+---------------+
| 10.10.111.122 |
| 10.10.111.123 |
| 10.10.111.124 |
| 10.10.111.125 |
| 10.10.242.211 |
| 10.10.242.111 |
| 10.10.242.211 |
+---------------+
7 rows in set (0.00 sec)
Why would the .11 search work and .111 not work and, when I use .11 to search, I get the .211 results as well?
Upvotes: 1
Views: 884
Reputation: 2588
the [[:>:]] is used for words and separates using alphanumeric characters or underscores. Dot is not alphanumeric. you are loking for a separated word in a string where the word is not separated (dot is part of the word).
just use WHERE INET_NTOA(ip) like "%.111"
Upvotes: 1
Reputation: 3809
Your regular expression is self-contradictory.
You are bounding your pattern on word boundaries, and then including a non-word character in the string you're looking for. Since the '.' character isn't a word character, there will never be any strings that are delimited by word boundaries that include the '.'.
Put another way, since the '.' is itself a word boundary, you are looking for [word-boundary][word-boundary][word], which cannot occur.
Just take out the word boundaries in your REGEXP:
WHERE INET_NTOA(ip) REGEXP '\.111'
Upvotes: 1