# Строковые функции

### CONCAT()
Конкатенирует две или более строк в одну. Аргументы, не являющиеся строками, должны быть явно преобразованы в строку с помощью функции `TO_STRING()`.

```sql
CONCAT(TO_STRING(float_attr), ',', TO_STRING(int_attr), ',', title)
```

### LEVENSHTEIN()
`LEVENSHTEIN ( pattern, source, {normalize=0, length_delta=0})` возвращает число (расстояние Левенштейна) односимвольных правок (вставок, удалений или замен) между строками `pattern` и `source`, необходимых для преобразования `pattern` в `source`.

   * `pattern`, `source` - константная строка, имя строкового поля, имя JSON поля или любое выражение, дающее строку (например, [SUBSTRING_INDEX()](../Functions/String_functions.md#SUBSTRING_INDEX%28%29))
   * `normalize` - опция возвращать расстояние в виде числа с плавающей запятой в диапазоне `[0.0 - 1.0]`, где 0.0 — точное совпадение, а 1.0 — максимальное различие. Значение по умолчанию 0, что означает не нормализовать и возвращать результат целым числом.
   * `length_delta` - пропускает вычисление расстояния Левенштейна и возвращает `max(strlen(pattern), strlen(source))`, если опция установлена, а длина строк отличается более чем на `length_delta`. Значение по умолчанию 0, что означает вычислять расстояние Левенштейна для любых входных строк. Эта опция может быть полезна при проверке преимущественно похожих строк.

``` sql
SELECT LEVENSHTEIN('gily', attr1) AS dist, WEIGHT() AS w FROM test WHERE MATCH('test') ORDER BY w DESC, dist ASC;
SELECT LEVENSHTEIN('gily', j.name, {length_delta=6}) AS dist, WEIGHT() AS w FROM test WHERE MATCH('test') ORDER BY w DESC;
SELECT LEVENSHTEIN(title, j.name, {normalize=1}) AS dist, WEIGHT() AS w FROM test WHERE MATCH ('test') ORDER BY w DESC, dist ASC;
```

### REGEX()
Функция `REGEX(attr,expr)` возвращает 1, если регулярное выражение совпадает со строкой атрибута, и 0 в противном случае. Работает как со строковыми, так и с JSON атрибутами.

```sql
SELECT REGEX(content, 'box?') FROM test;
SELECT REGEX(j.color, 'red | pink') FROM test;
```

Выражения должны соответствовать синтаксису RE2. Для выполнения поиска без учета регистра, например, можно использовать:
```sql
SELECT REGEX(content, '(?i)box') FROM test;
```

### SNIPPET()
Функция `SNIPPET()` используется для выделения результатов поиска в заданном тексте. Первые два аргумента — это текст для выделения и запрос. [Опции](../Searching/Highlighting.md#Highlighting-options) могут передаваться функции как третий, четвертый и последующие аргументы. `SNIPPET()` может получать текст для выделения напрямую из таблицы. В этом случае первым аргументом должно быть имя поля:

```sql
SELECT SNIPPET(body, QUERY()) FROM myIndex WHERE MATCH('my.query')
```

В этом примере выражение `QUERY()` возвращает текущий полнотекстовый запрос. `SNIPPET()` также может выделять неиндексированный текст:

```sql
mysql  SELECT id, SNIPPET('text to highlight', 'my.query', 'limit=100') FROM myIndex WHERE MATCH('my.query')
```

Дополнительно, его можно использовать для выделения текста, полученного из других источников с помощью пользовательской функции (UDF):

```sql
SELECT id, SNIPPET(myUdf(id), 'my.query', 'limit=100') FROM myIndex WHERE MATCH('my.query')
```

В данном контексте `myUdf()` — это функция, определённая пользователем (UDF), которая извлекает документ по его ID из внешнего источника хранения. Функция `SNIPPET()` является "post limit" функцией, что означает, что вычисление снитпетов откладывается до тех пор, пока не будет подготовлен весь окончательный набор результатов, и даже после применения оператора `LIMIT`. Например, если используется `LIMIT 20,10`, то `SNIPPET()` будет вызвана не более 10 раз.

Важно отметить, что `SNIPPET()` не поддерживает ограничения по полям. Для этой функциональности используйте [HIGHLIGHT()](../Searching/Highlighting.md#Highlighting-via-SQL).

### SUBSTRING_INDEX()

<!-- example substring_index -->
`SUBSTRING_INDEX(string, delimiter, number)` возвращает подстроку исходной строки, основанную на указанном числе вхождений разделителя:

   *   string - исходная строка, которая может быть константной или строкой из строкового/JSON атрибута.
   *   delimiter - разделитель для поиска.
   *   number - количество раз для поиска разделителя. Может быть положительным или отрицательным числом. Если число положительное, функция возвращает всё, что слева от разделителя. Если число отрицательное, функция возвращает всё, что справа от разделителя.

По умолчанию `SUBSTRING_INDEX()` возвращает строку, но при необходимости её можно привести к другим типам (например, целому или вещественному числу). Числовые значения можно конвертировать с помощью специальных функций (например, `BIGINT()`, `DOUBLE()` и т.д.).

<!-- request SQL -->
```sql
SELECT SUBSTRING_INDEX('www.w3schools.com', '.', 2) FROM test;
SELECT SUBSTRING_INDEX(j.coord, ' ', 1) FROM test;
SELECT          SUBSTRING_INDEX('1.2 3.4', ' ',  1);  /* '1.2' */
SELECT          SUBSTRING_INDEX('1.2 3.4', ' ', -1);  /* '3.4' */
SELECT sint (   SUBSTRING_INDEX('1.2 3.4', ' ',  1)); /* 1 */
SELECT sint (   SUBSTRING_INDEX('1.2 3.4', ' ', -1)); /* 3 */
SELECT double ( SUBSTRING_INDEX('1.2 3.4', ' ',  1)); /* 1.200000 */
SELECT double ( SUBSTRING_INDEX('1.2 3.4', ' ', -1)); /* 3.400000 */
```

<!-- end -->

### UPPER() и LOWER()

`UPPER(string)` преобразует аргумент в верхний регистр, `LOWER(string)` — в нижний регистр.

Результат также может быть приведён к числовому типу, но только если строковый аргумент может быть преобразован в число. Числовые значения могут быть приведены с помощью произвольных функций (`BITINT`, `DOUBLE` и т.п.).

```sql
SELECT upper('www.w3schools.com', '.', 2); /* WWW.W3SCHOOLS.COM  */
SELECT double (upper ('1.2e3')); /* 1200.000000 */
SELECT integer (lower ('12345')); /* 12345 */
```
<!-- proofread -->

