【问题标题】:MYSQL REGEXP INET_NTOA IP ADDRESS SEARCHINGMYSQL REGEXP INET_NTOA IP 地址搜索
【发布时间】:2013-10-14 03:19:37
【问题描述】:

我无法理解为什么我从 MySQL 查询 IP 地址中得到以下结果。我将 IP 地址存储为 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)

这是将 INTEGERS 转换为 IP 地址时数据的样子。

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)

当我搜索特定子网(例如 111)时,我得到了我期望的结果:

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)

如果我在查询中使用小数,则不会得到任何结果。

mysql> SELECT INET_NTOA(ip) AS ip FROM ipaddress WHERE INET_NTOA(ip) REGEXP '[[:<:]]\.111[[:>:]]';
Empty set (0.00 sec)

如果我将搜索查询更改为 0.11,则查询中的小数点有效。不过,这一次,我得到了所有的 .111、和 .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)

为什么 .11 搜索有效而 .111 无效,当我使用 .11 搜索时,我也得到了 .211 结果?

【问题讨论】:

  • 与您的实际问题不同,我只想指出,将 IP 地址存储为整数是一个奇怪的选择。你空间很紧吗?或者你正在对它们做一些花哨的数学运算?如果您将它们存储为(稍大的)字符串,您将永远不需要进行进出 Internet 地址格式的转换。
  • 我的空间并不紧张。实际上,我已经将 IP 地址存储为字符串很长时间了,但是当我最近发现 MySQL 的 INET_NTOA 函数允许我将 IP 存储为整数时,我认为在按 IP 地址排序时这是一个更好的解决方案。我同意你的观点,将它们存储为字符串是一种更简单的解决方案。

标签: mysql regex ip-address


【解决方案1】:

你的正则表达式是自相矛盾的。

您将模式限制在单词边界上,然后在您要查找的字符串中包含一个非单词字符。由于'.'字符不是单词字符,永远不会有任何由包含“。”的单词边界分隔的字符串。

换一种说法,因为'.'本身就是一个词的边界,你正在寻找[word-boundary][word-boundary][word],它不可能出现。

只需去掉 REGEXP 中的单词边界:

WHERE INET_NTOA(ip) REGEXP '\.111'

【讨论】:

  • 如果您坚持将 IP 地址存储为整数,请务必将它们设为 UNSIGNED 整数,否则您将截断地址账单而不是 '127。 ...'
【解决方案2】:

[[:>:]] 用于单词并使用字母数字字符或下划线分隔。点不是字母数字。您正在寻找未分隔的字符串中的分隔单词(点是单词的一部分)。 只需使用WHERE INET_NTOA(ip) like "%.111"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-25
    • 2017-07-30
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 2016-02-04
    • 1970-01-01
    相关资源
    最近更新 更多