В MySQL реализовано стандартное для SQL сравнение по шаблонам, а также особый тип такого сравнения - он основан на использовании выражений, подобных применяющимся в служебных программах Unix (таких, как vi, grep и sed).
В SQL при сравнении по шаблону символ `_' обозначает любой одиночный
символ, а `%' - определенное количество символов (включая ноль символов).
В MySQL в SQL-шаблонах по умолчанию не учитывается регистр символов. При
работе с шаблонами SQL использование операторов =
или <>
не допускается,
вместо этого применяются операторы сравнения LIKE
или NOT LIKE
.
Найти все имена, начинающиеся с `b', можно следующим образом:
mysql> SELECT * FROM pet WHERE name LIKE "b%"; +--------+--------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +--------+--------+---------+------+------------+------------+ | Buffy | Harold | dog | f | 1989-05-13 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | +--------+--------+---------+------+------------+------------+
Найти все имена, заканчивающиеся на `fy', можно следующим образом:
mysql> SELECT * FROM pet WHERE name LIKE "%fy"; +--------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +--------+--------+---------+------+------------+-------+ | Fluffy | Harold | cat | f | 1993-02-04 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +--------+--------+---------+------+------------+-------+
Найти все имена, содержащие `w', можно следующим образом:
mysql> SELECT * FROM pet WHERE name LIKE "%w%"; +----------+-------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+------------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | | Whistler | Gwen | bird | NULL | 1997-12-09 | NULL | +----------+-------+---------+------+------------+------------+
Найти все имена, содержащие ровно пять символов, можно при помощи шаблонного символа `_':
mysql> SELECT * FROM pet WHERE name LIKE "_____"; +-------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +-------+--------+---------+------+------------+-------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +-------+--------+---------+------+------------+-------+
Во втором типе шаблонов, предусмотренных в MySQL, используются расширенные
регулярные выражения. При поиске совпадений на основе такого шаблона
шаблоном нужно пользоваться операторами REGEXP
и NOT REGEXP
(или их
синонимами - RLIKE
и NOT RLIKE
).
Ниже приведены некоторые характеристики расширенных регулярных выражений:
Чтобы продемонстрировать работу регулярных выражений, приведенные выше
запросы LIKE
здесь переписаны с использованием REGEXP
.
Найти все имена, начинающиеся с `b', можно при помощи символа `^', привязывающего шаблон к началу имени:
mysql> SELECT * FROM pet WHERE name REGEXP "^b"; +--------+--------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +--------+--------+---------+------+------------+------------+ | Buffy | Harold | dog | f | 1989-05-13 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | +--------+--------+---------+------+------------+------------+
В версиях MySQL до 3.23.4 REGEXP
учитывает регистр символов, и приведенный
запрос не возвратит никаких результатов. Для поиска символов `b' верхнего
или нижнего регистра воспользуйтесь следующим запросом:
mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
Начиная с версии MySQL 3.23.4, заставить REGEXP
учитывать регистр символов
можно с помощью ключевого слова BINARY
. В этом запросе положительный
результат поиска будет получен только при обнаружении символа 'b' нижнего
регистра в начале имени:
mysql> SELECT * FROM pet WHERE name REGEXP BINARY "^b";
Найти все имена, заканчивающиеся на `fy', можно при помощи символа `$', привязывающего шаблон к концу имени:
mysql> SELECT * FROM pet WHERE name REGEXP "fy$"; +--------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +--------+--------+---------+------+------------+-------+ | Fluffy | Harold | cat | f | 1993-02-04 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +--------+--------+---------+------+------------+-------+
Найти все имена, содержащие символ `w' любого регистра, можно так:
mysql> SELECT * FROM pet WHERE name REGEXP "w"; +----------+-------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+------------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | | Whistler | Gwen | bird | NULL | 1997-12-09 | NULL | +----------+-------+---------+------+------------+------------+
Поскольку регулярное выражение выдает положительный результат при совпадении шаблона с любым фрагментом значения, в приведенном выше примере привязывать поиск к любому из концов имени для сравнения полного значения с шаблоном, как это пришлось бы делать для шаблона SQL, не нужно.
Найти все имена, содержащие ровно пять символов, можно, если привязать поиск к началу и концу имени с помощью символов `^' и `$' и поставить пять символов `.' между ними:
mysql> SELECT * FROM pet WHERE name REGEXP "^.....$"; +-------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +-------+--------+---------+------+------------+-------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +-------+--------+---------+------+------------+-------+
Предыдущий запрос можно записать и при помощи оператора `{n}'
(``повторить-n
-раз''):
mysql> SELECT * FROM pet WHERE name REGEXP "^.{5}$"; +-------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +-------+--------+---------+------+------------+-------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +-------+--------+---------+------+------------+-------+
User Comments
You can also store pattern in you database fields and use syntax like this:
SELECT country FROM ip_list WHERE '127.0.0.1' like ip
where ip is the field name with patterns.
It should be noted that if you wish to match a literal $ in your regexp, you must double escape it, not single escape.
Subject: '$PATH/module'
PATTERN: REGEXP '^\\$PATH/[^/]+/?$'
RESULT: 1
Subject: '$PATH/module'
PATTERN: REGEXP '^\$PATH/[^/]+/?$'
RESULT: 0
... and if you want to select info that does _not_ match a particular pattern, say, at the end of a field, do this:
SELECT * FROM `table` WHERE field not LIKE "%foo"
"`[a-z]' matches any letter, whereas `[0-9]' matches any digit."
[a-z] doesn't match Ь or К as in BjЬrn or EzechiКl.
To match BjЬrn you could use REGEXP '^..[[:alnum:]]..$'
There should be a function like
integer STRSPN(string1, string2)
(see same function name and meaning in PHP4!)
which counts the numbers of equal characters in string1 and string2, beginning with the first characters in each and sttopping by the first unequal character:
STRSPN("horsepower","horseshoe") = 5
STRSPN("foo", "bar") = 0 (an obligatory example! :-))
STRSPN("horsecat", "ho") = 2
...
The "moral justification" :-) of this feature request is that the number of adjacent characters is at hand anyway at every string comparison and needs no extra calculations!
(Well maybe the normal comparison algorithm compares 4 bytes at once... but there should be a solution...)
Without this function, things have to be made with much more hassle and subqueries and so on...
How do you find the position of a match?
I.e. the old M$-SQL
selct "pingu and sealie" patindex( "* and *" );
-> 6
Add your own comment.