2015-07-01 4 views
2

Я использую RLIKE для поиска доменов электронной почты с помощью mysql.Поведение MySQL RLIKE для нумерованной строки

Вот запрос:

SELECT something 
FROM table1 
WHERE SUBSTRING_INDEX(table1.email, "@", -1) RLIKE "test1.com"|"test2.com" 

Это соответствует все домены электронной почты с номерами в, например:

[email protected] 

Любая идея, почему?

EDIT: Я также заметил, что он находит домены электронной почты, которые имеют как минимум две последовательные цифры.

Действительно странно.

+0

Вы можете разместить набор образцов строк, чтобы соответствовать ? Я думаю, что произошло то, что '|' интерпретируется как [побитовое ИЛИ] (https://dev.mysql.com/doc/refman/5.0/en/non-typed-operators.html), потому что внешнее регулярное выражение не заключенные в одинарные кавычки. Вероятно, это привело к тому, что все регулярное выражение было добавлено в строку '' 0 ''. –

ответ

4

Строка, переданная в RLIKE или REGEXP, должна быть строка с кавычками, в которой все регулярное выражение однокасканное. У вас две строки с двумя кавычками, разделенные |, что составляет the bitwise OR operator.

Это вызывает все выражение, которое будет оценено как 0, и именно поэтому домен [email protected] подобран:

# 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 с одной кавычками, и backslash- побегите .. Я также добавляю якорь ^$, поэтому подстроки не совпадают.

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') 
+0

Отлично, это очень помогло. Благодарю. –

+0

@ Милош Рад помочь, удачи. –