---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ydb.tech/docs/en/yql/reference/udf/list/pire.md
  - https://ydb.tech/docs/ru/yql/reference/udf/list/pire.md
sourcePath: ru/core/yql/reference/udf/list/pire.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ydb.tech/docs/ru/llms.txt

# Pire

## Список функций

* `Pire::Grep(pattern:String) -> (string:String?) -> Bool`
* `Pire::Match(pattern:String) -> (string:String?) -> Bool`
* `Pire::MultiGrep(pattern:String) -> (string:String?) -> Tuple<Bool, Bool, ...>`
* `Pire::MultiMatch(pattern:String) -> (string:String?) -> Tuple<Bool, Bool, ...>`
* `Pire::Capture(pattern:String) -> (string:String?) -> String?`
* `Pire::Replace(pattern:String) -> (string:String?, replacement:String) -> String?`

Одной из опций для поиска по регулярным выражениям в YQL является библиотека [Pire](https://github.com/yandex/pire) (Perl Incompatible Regular Expressions). Это разработанная в Яндексе очень быстрая библиотека регулярных выражений: на нижнем уровне она просматривает входную строку один раз, подряд, без откатов, и тратит (на x86 и x86_64) по 5 инструкций на символ.

Скорость работы достигается за счет некоторых разумных ограничений:

* Библиотека Pire ориентирована прежде всего на проверку на совпадение строки с регулярным выражением (Match).
* Возможность вернуть совпавшую подстроку тоже поддерживается (Capture), но с ограничениями (возвращает совпадение только с одной группой).

По умолчанию все функции работают в однобайтовом режиме, но если регулярное выражение является валидной UTF-8 строкой, но не является валидной ASCII строкой, — автоматически включается режим UTF-8.

Чтобы включить Unicode-режим, можно вставить в выражение один символ за пределами ASCII с оператором `?`, например `\\w+я?`.

## Синтаксис вызова {#call-syntax}

Чтобы избежать компиляции регулярного выражения на каждой строке таблицы, необходимо обернуть вызов функции в [именованное выражение](https://ydb.tech/docs/ru/yql/reference/syntax/expressions.md#named-nodes):

```yql
$re = Pire::Grep("\\d+"); -- создаем вызываемое значение для проверки конкретного регулярного выражения
SELECT * FROM table WHERE $re(key); -- используем его для фильтрации таблицы
```

{% note alert %}

При экранировании спецсимволов в регулярном выражении нужен второй слеш, так как все стандартные строковые литералы в SQL могут принимать С-escaped строки, а последовательность `\d` не является валидной последовательностью, и даже если бы являлась — не приводила бы к ожидаемому эффекту поиска чисел.

{% endnote %}

Есть возможность отключить чувствительность к регистру (то есть включить case-insensitive режим), указав в начале регулярного выражения флаг `(?i)`.

### Примеры

```yql
$value = "xaaxaaxaa";
$match = Pire::Match("a.*");
$grep = Pire::Grep("axa");
$insensitive_grep = Pire::Grep("(?i)axa");
$multi_match = Pire::MultiMatch(@@a.*
.*a.*
.*a
.*axa.*@@);
$capture = Pire::Capture(".*x(a).*");
$capture_many = Pire::Capture(".*x(a+).*");
$replace = Pire::Replace(".*x(a).*");

SELECT
  $match($value) AS match,                        -- false
  $grep($value) AS grep,                          -- true
  $insensitive_grep($value) AS insensitive_grep,  -- true
  $multi_match($value) AS multi_match,            -- (false, true, true, true)
  $multi_match($value).0 AS some_multi_match,     -- false
  $capture($value) AS capture,                    -- "a"
  $capture_many($value) AS capture_many,          -- "aa"
  $replace($value, "b") AS replace;               -- "xaaxaaxba"
```

## Grep {#grep}

Проверяет совпадение регулярного выражения с **частью строки** (произвольной подстрокой).

## Match {#match}

Проверяет совпадение регулярного выражения **со строкой целиком**.
Чтобы получить результат, аналогичный `Grep` (где учитывается совпадение с подстрокой), нужно обернуть регулярное выражение с обоих сторон в `.*`, например `.*foo.*` вместо `foo`.

## MultiGrep / MultiMatch {#multigrep}

Библиотека Pire предоставляет возможность за один проход по тексту проверить несколько регулярных выражений и получить по каждому из них отдельный ответ.
С помощью функций MultiGrep/MultiMatch можно оптимизировать скорость выполнения запроса, но это нужно делать осмотрительно, поскольку размер используемого для проверки конечного автомата растет экспоненциально с числом регулярных выражений:

* Если вас интересует совпадение строки с любым из перечисленных выражений (результаты объединяются через «или»), то намного эффективнее сделать одно регулярное выражение, объединив части с помощью оператора `|`, и использовать для поиска обычный Grep или Match.
* В библиотеке Pire установлен лимит на размер конечного автомата (в YQL используется значение этого лимита, установленное по умолчанию в библиотеке). Если лимит превышен, при запуске запроса вернется ошибка `Failed to glue up regexes, probably the finite state machine appeared to be too large`.

При вызове функций MultiGrep/MultiMatch регулярные выражения передаются по одному на строку с использованием [многострочных строковых литералов](https://ydb.tech/docs/ru/yql/reference/syntax/expressions.md#multiline-string-literals):

### Примеры

```yql
$multi_match = Pire::MultiMatch(@@a.*
.*x.*
.*axa.*@@);

SELECT
    $multi_match("a") AS a,      -- (true, false, false)
    $multi_match("axa") AS axa;  -- (true, true, true)
```

## Capture {#capture}

При совпадении строки с указанным регулярным выражением возвращает подстроку, совпавшую с группой, отмеченной в регулярном выражении круглыми скобками.
Capture работает НЕ в жадном режиме, то есть возвращается самая короткая подстрока из возможных.

{% note alert %}

В выражении должна быть ровно **одна** группа, обозначенная круглыми скобками. В случае отсутствия совпадения возвращается `NULL` (пустой Optional).

{% endnote %}

Если описанные выше ограничения и особенности по каким-либо причинам выглядят неприемлемыми, рекомендуется рассмотреть возможность использования [Re2::Capture](https://ydb.tech/docs/ru/yql/reference/udf/list/re2.md#capture).

## Replace {#replace}

В библиотеке Pire отсутствует функция замены по регулярному выражению. Функция `Pire::Replace` в YQL представляет собой упрощенную эмуляцию, реализованную с помощью `Capture`. Может работать некорректно, если найденная подстрока встречается в исходной более одного раза.

Как правило, лучше воспользоваться [Re2::Replace](https://ydb.tech/docs/ru/yql/reference/udf/list/re2.md#replace) вместо неё.
