Синтаксис регулярных выражений
Регулярное выражение (regex) — это способ определения шаблонов поиска с использованием специальных символов и операторов. Эти шаблоны позволяют вам сопоставлять последовательности символов в строках.
В OpenSearch вы можете использовать регулярные выражения в следующих типах запросов:
regexp
query_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
.