Синтаксис регулярных выражений
Регулярное выражение (regex) — это способ определения шаблонов поиска с использованием специальных символов и операторов. Эти шаблоны позволяют вам сопоставлять последовательности символов в строках.
В OpenSearch вы можете использовать регулярные выражения в следующих типах запросов:
regexpquery_string
OpenSearch использует движок регулярных выражений Apache Lucene, который имеет свой собственный синтаксис и ограничения. Он не использует регулярные выражения, совместимые с Perl (PCRE), поэтому некоторые знакомые функции регулярных выражений могут вести себя иначе или не поддерживаться.
Выбор между запросами regexp и query_string
Оба запроса regexp и query_string поддерживают регулярные выражения, но они ведут себя по-разному и служат для разных случаев использования.
| Особенность | Запрос regexp | Запрос query_string |
|---|---|---|
| Сопоставление шаблонов | Шаблон regex должен соответствовать всему значению поля | Шаблон regex может соответствовать любой части поля |
| Поддержка флагов | Флаги включают необязательные операторы regex | Флаги не поддерживаются |
| Тип запроса | Запрос на уровне термина (не оценивается) | Полнотекстовый запрос (оценивается и разбирается) |
| Лучший случай использования | Строгое сопоставление шаблонов для полей типа keyword или exact | Поиск в анализируемых полях с использованием гибкой строки запроса, поддерживающей шаблоны regex |
| Сложная композиция запросов | Ограничена шаблонами regex | Поддерживает AND, OR, подстановочные знаки, поля, увеличение и другие функции. См. Запрос query_string. |
Зарезервированные символы
Движок регулярных выражений Lucene поддерживает все символы Unicode. Однако следующие символы рассматриваются как специальные операторы:
. ? + * | { } [ ] ( ) " \
В зависимости от включенных флагов, которые указывают необязательные операторы, следующие символы также могут быть зарезервированы:
@ & ~ < >
Чтобы сопоставить эти символы буквально, либо экранируйте их с помощью обратной косой черты (), либо оберните всю строку в двойные кавычки:
\&: Сопоставляет литерал &\\: Сопоставляет литерал обратной косой черты ()"hello@world": Сопоставляет полную строку hello@world
Стандартные операторы регулярных выражений
Lucene поддерживает основной набор операторов регулярных выражений:
-
. – Сопоставляет любой одиночный символ. Пример:
f.nсоответствует f, за которым следует любой символ, а затем n (например, fan или fin). -
? – Сопоставляет ноль или один из предыдущих символов. Пример:
colou?rсоответствует color и colour. -
+ – Сопоставляет один или более из предыдущих символов. Пример:
go+соответствует g, за которым следует один или более o (go, goo, gooo и так далее). -
* – Сопоставляет ноль или более из предыдущих символов. Пример:
lo*seсоответствует l, за которым следует ноль или более o, а затем se (lse, lose, loose, loooose и так далее). -
{min,max} – Сопоставляет конкретный диапазон повторений. Если max опущен, нет верхнего предела на количество сопоставляемых символов. Пример:
x{3}соответствует ровно 3 x (xxx);x{2,4}соответствует от 2 до 4 x (xx, xxx или xxxx);x{3,}соответствует 3 или более x (xxx, xxxx, xxxxx и так далее). -
| – Действует как логическое ИЛИ. Пример:
apple|orangeсоответствует apple или orange. -
( ) – Группирует символы в подпаттерн. Пример:
ab(cd)?соответствует ab и abcd. -
[ ] – Сопоставляет один символ из набора или диапазона. Пример:
[aeiou]соответствует любой гласной. -
- – Когда предоставляется внутри скобок, указывает диапазон, если не экранирован или является первым символом внутри скобок. Пример:
[a-z]соответствует любой строчной букве;[-az]соответствует -, a или z;[a\\-z]соответствует a, -, или z. -
^ – Когда предоставляется внутри скобок, действует как логическое НЕ, отрицая диапазон символов или любой символ в наборе. Пример:
[^az]соответствует любому символу, кроме a или z;[^a-z]соответствует любому символу, кроме строчных букв;[^-az]соответствует любому символу, кроме -, a и z;[^a\\-z]соответствует любому символу, кроме a, -, и z.
Необязательные операторы
Вы можете включить дополнительные операторы регулярных выражений, используя параметр flags. Разделяйте несколько флагов с помощью |.
Следующие флаги доступны:
-
ALL (по умолчанию) – Включает все необязательные операторы.
-
COMPLEMENT – Включает
~, который отрицает следующее выражение. Пример:d~efсоответствует dgf, dxf, но не def. -
INTERSECTION – Включает
&как логический оператор И. Пример:ab.+&.+cdсоответствует строкам, содержащим ab в начале и cd в конце. -
INTERVAL – Включает синтаксис
<min-max>для сопоставления числовых диапазонов. Пример:id<10-12>соответствует id10, id11 и id12. -
ANYSTRING – Включает
@для сопоставления любой строки. Вы можете комбинировать это с~и&для исключений. Пример:@&.*error.*&.*[0-9]{3}.*соответствует строкам, содержащим как слово “error”, так и последовательность из трех цифр.
Неподдерживаемые функции
Движок Lucene не поддерживает следующие часто используемые якоря регулярных выражений:
- ^ – Начало строки
- $ – Конец строки
Вместо этого ваш шаблон должен соответствовать всей строке, чтобы произвести совпадение.
Пример использования регулярных выражений
Чтобы попробовать регулярные выражения, индексируйте следующие документы в индекс logs:
PUT /logs/_doc/1
{
"message": "error404"
}
PUT /logs/_doc/2
{
"message": "error500"
}
PUT /logs/_doc/3
{
"message": "error1a"
}
Пример: Базовый запрос с использованием регулярных выражений
Следующий запрос regexp возвращает документы, в которых полное значение поля message соответствует шаблону “error”, за которым следует одна или более цифр. Значение не соответствует, если оно содержит шаблон только как подстроку:
GET /logs/_search
{
"query": {
"regexp": {
"message": {
"value": "error[0-9]+"
}
}
}
}
Этот запрос соответствует error404 и error500:
{
"took": 28,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "logs",
"_id": "1",
"_score": 1,
"_source": {
"message": "error404"
}
},
{
"_index": "logs",
"_id": "2",
"_score": 1,
"_source": {
"message": "error500"
}
}
]
}
}
Пример: Использование необязательных операторов
Следующий запрос соответствует документам, в которых поле message точно соответствует строке, начинающейся с “error”, за которой следует число от 400 до 500, включительно. Флаг INTERVAL позволяет использовать синтаксис <min-max> для числовых диапазонов:
GET /logs/_search
{
"query": {
"regexp": {
"message": {
"value": "error<400-500>",
"flags": "INTERVAL"
}
}
}
}
Этот запрос также соответствует error404 и error500:
{
"took": 22,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "logs",
"_id": "1",
"_score": 1,
"_source": {
"message": "error404"
}
},
{
"_index": "logs",
"_id": "2",
"_score": 1,
"_source": {
"message": "error500"
}
}
]
}
}
Пример: Использование ANYSTRING
Когда флаг ANYSTRING включен, оператор @ соответствует всей строке. Это полезно в сочетании с пересечением (&), поскольку позволяет вам строить запросы, которые соответствуют полным строкам при определенных условиях.
Следующий запрос соответствует сообщениям, которые содержат как слово “error”, так и последовательность из трех цифр. Используйте ANYSTRING, чтобы утверждать, что все поле должно соответствовать пересечению обоих шаблонов:
GET /logs/_search
{
"query": {
"regexp": {
"message.keyword": {
"value": "@&.*error.*&.*[0-9]{3}.*",
"flags": "ANYSTRING|INTERSECTION"
}
}
}
}
Этот запрос соответствует error404 и error500:
{
"took": 20,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "logs",
"_id": "1",
"_score": 1,
"_source": {
"message": "error404"
}
},
{
"_index": "logs",
"_id": "2",
"_score": 1,
"_source": {
"message": "error500"
}
}
]
}
}
Обратите внимание, что этот запрос также будет соответствовать xerror500, error500x и errorxx500.