MySQL 编号字符串的 RLIKE 行为
MySQL RLIKE behaviour for numbered string
我正在使用 RLIKE 查找一些 mysql 的电子邮件域。
这是查询:
SELECT something
FROM table1
WHERE SUBSTRING_INDEX(table1.email, "@", -1) RLIKE "test1.com"|"test2.com"
这匹配了所有带有数字的电子邮件域,例如:
aaa@domain0.com
知道为什么吗?
编辑:我还注意到它会找到至少有两个连续数字的电子邮件域。
真奇怪
提供给RLIKE
或REGEXP
的字符串需要是带引号的字符串,其中整个正则表达式是单引号。你有两个用 |
分隔的双引号字符串,即 the bitwise OR operator.
这导致整个表达式被评估为 0
,这就是匹配域 aaa@domain0.com
的原因:
# The unquoted | evaluates this to zero:
mysql> SELECT "string" | "string";
+---------------------+
| "string" | "string" |
+---------------------+
| 0 |
+---------------------+
# And zero matches domain0.com
mysql> SELECT 'domain0.com' RLIKE '0';
+-------------------------+
| 'domain0.com' RLIKE '0' |
+-------------------------+
| 1 |
+-------------------------+
相反,您需要将 RLIKE
与单引号字符串一起使用,并使用反斜杠转义 .
。我还添加了 ^$
锚点,因此子字符串不匹配。
WHERE SUBSTRING_INDEX(table1.email, "@", -1) RLIKE '^test1\.com$|^test2\.com$'
也可以表示为'^(test1\.com|test2\.com)$'
。诀窍是 |
的优先级非常低,因此您需要确保两端都锚定了您想要匹配的每个可能的字符串。
但是,如果您只是想匹配域列表,使用 IN ()
会容易得多,因此您可以只列出它们:
WHERE SUBSTRING_INDEX(table1.email, "@", -1) IN ('test1.com', 'test2.com', 'test4.org')
我正在使用 RLIKE 查找一些 mysql 的电子邮件域。
这是查询:
SELECT something
FROM table1
WHERE SUBSTRING_INDEX(table1.email, "@", -1) RLIKE "test1.com"|"test2.com"
这匹配了所有带有数字的电子邮件域,例如:
aaa@domain0.com
知道为什么吗?
编辑:我还注意到它会找到至少有两个连续数字的电子邮件域。
真奇怪
提供给RLIKE
或REGEXP
的字符串需要是带引号的字符串,其中整个正则表达式是单引号。你有两个用 |
分隔的双引号字符串,即 the bitwise OR operator.
这导致整个表达式被评估为 0
,这就是匹配域 aaa@domain0.com
的原因:
# The unquoted | evaluates this to zero:
mysql> SELECT "string" | "string";
+---------------------+
| "string" | "string" |
+---------------------+
| 0 |
+---------------------+
# And zero matches domain0.com
mysql> SELECT 'domain0.com' RLIKE '0';
+-------------------------+
| 'domain0.com' RLIKE '0' |
+-------------------------+
| 1 |
+-------------------------+
相反,您需要将 RLIKE
与单引号字符串一起使用,并使用反斜杠转义 .
。我还添加了 ^$
锚点,因此子字符串不匹配。
WHERE SUBSTRING_INDEX(table1.email, "@", -1) RLIKE '^test1\.com$|^test2\.com$'
也可以表示为'^(test1\.com|test2\.com)$'
。诀窍是 |
的优先级非常低,因此您需要确保两端都锚定了您想要匹配的每个可能的字符串。
但是,如果您只是想匹配域列表,使用 IN ()
会容易得多,因此您可以只列出它们:
WHERE SUBSTRING_INDEX(table1.email, "@", -1) IN ('test1.com', 'test2.com', 'test4.org')