【问题标题】:Mysql field name within regular expression正则表达式中的Mysql字段名称
【发布时间】:2009-09-22 15:55:29
【问题描述】:

我有下表

Table bots{
    ip_address varchar(15),
    bot_name varchar(32)
}

鉴于一些机器人有静态 ips 而其他没有,该表有诸如 192.168.0 和 192.168.1.15 之类的条目

现在我必须查看给定的 ip 是否属于机器人。我在考虑这些方面的事情

SELECT bot_name
FROM bots
WHERE __input_ip__  REGEXP '^ip_address'

但这不起作用,原因很明显,它正在寻找以 ip_address 开头的字符串。

所以我的问题是,如何在 sql 正则表达式中包含字段名称?

【问题讨论】:

  • 那么 192.168.1.15 和 192.168.1.150, 192.168.1.151, ..., 192.168.1.159 将被阻止,因为它们都以 192.168.1.15 开头?
  • @gumbo,说得好。我没想到。如果 ip 是 192.168.1.15 我希望它忽略 *.150 , *.151 , *152 ...

标签: sql mysql regex


【解决方案1】:

您可能需要考虑将 IP 地址存储为 INT UNSIGNED。还要存储网络掩码,以便区分静态地址和子网。

INSERT INTO bots (ipaddress, netmask, bot_name) 
VALUES (INET_ATOI('192.168.1.0'), INET_ATOI('255.255.255.0'), 'Wall-E');

然后可以查询输入的IP地址是否匹配:

SELECT bot_name
FROM bots
WHERE __input_ip__ & netmask = ipaddress & netmask;

对 IP 地址使用整数而不是 CHAR(15) 是一种常见的优化。即使存储 IP 地址和网络掩码的 8 个字节也只是 CHAR(15) 存储的一半多一点。并且按位运算可能比正则表达式匹配快很多,并且更容易避免像@Gumbo评论中的极端情况。

【讨论】:

  • 我喜欢这种方法,但我想我一定是遗漏了一些东西 INSERT into bots(ip_address, network_mask, name) VALUES (INET_ATON('192.168.0.0'), INET_ATON('255.255.255.0') , 'Wall-E'), (INET_ATON('192.168.1.15'), INET_ATON('255.255.255.0'), 'Bender'); #Returns wall-e SELECT name FROM bots WHERE ip_address = INET_ATON('192.168.0.15') & network_mask; # 返回一个空集 SELECT name FROM bots WHERE ip_address = INET_ATON('192.168.1.15') & network_mask;
  • 好的,很抱歉混淆了,我虽然你总是使用'​​0'作为动态IP地址的可变部分(虽然我不知道为什么我会这样想)。我已经编辑了上面的答案,将网络掩码应用于 ip_address 和输入。
【解决方案2】:

试试这个:

SELECT bot_name
FROM bots
WHERE __input_ip__  REGEXP concat('^', replace(ip_address, '.', '\.'))

【讨论】:

  • ip_address 中的. 字符不会被正则表达式解释为“任何字符”吗?它们应该用反斜杠转义,可能是replace()
【解决方案3】:

(这是对 Andrew 的回答,但不适合评论。)

WHERE __input_ip__  REGEXP concat('^', replace(ip_address, '.', '\.'))

好计划,除了在 MySQL 中 \ 是一个(非标准 SQL)字符串文字转义,所以要在正则表达式中获得一个,你可能需要 '\\\.'

...除了在 ANSI 模式下它不会。啊!为了兼容,您必须以另一种方式获得反斜杠:

WHERE __input_ip__ REGEXP CONCAT('^', REPLACE(ip_address, '.', CHAR(92, 46)))

呃。也许最好忘记正则表达式并使用字符串操作:

WHERE LEFT(__input_ip__, CHAR_LENGTH(ip_address))=__input_ip__

【讨论】:

    猜你喜欢
    • 2017-10-30
    • 2022-12-15
    • 2010-09-21
    • 2021-03-14
    • 1970-01-01
    • 2011-05-11
    • 2019-08-09
    相关资源
    最近更新 更多